+HCU
Project 4: CD-ROM related reverse engineering
CD ROM from top to down
(MSCDEX, reversing drivers and CR-ROM related interrupts)
by +RCG
(13 October 1997)
Courtesy of Fravia's page
of reverse engineering
Well, a welcome "basic" addition by +Rcg, who clear things a little out on
such important matters like accessing the CD-ROM through the MSCDEX driver.
CD-ROM REVERSE ENGINEERING
Well under this generic title, I hope we will be able to
develop a good project, just like +HCU's Project 2 (Softice).
If you have read Project 2, you could see how many
different subjects are dealed there: Vxd, NT, CheckSums and
many others, would our objective only have been 'Crack', our
Project would have finished with Part 1 or 2.
Yet no! We want to learn as much as possible, so that when everyone of
us put his 'grain of sand', the result is a great project.
So thi is my own 'grain of sand' for project 4, and I wish we will have
a desert soon.
CD-ROM FROM TOP TO DOWN.
You know CD-ROM is a relatively 'new' hardware device, and it
has special characteristics that old MS-DOS can't use directly.
So, we need under MS-DOS a driver and a program called
MSCDEX (MS-CD-Extension).
For programmers, the CD drive is just like all the others drives
(this is the advantadges of a well designed OS, to isolate the
hard from de soft.
CD-ROM has another problem, it is a drive, so it must be
treated as a 'block device driver' but due to its capacity,
and the form it stores the information, it can't be
considered as a 'standart block device driver', so MS solved
this using MSCDEX, this program is a pseudoblockdevicedriver
that assings a 'letter' to the 'characther device driver',
to perform this action MSCDEX 'tells' MS-DOS CD-ROM it is a
net device, so MS-DOS accepts and gives it a 'letter'.
So we have two 'layers' between the hardware and the user:
net net
redirector call
Programm ----> DOS ----> MSCDEX -----> REDIRECTOR
Aplication KERNEL |
^ |
| |
| V
Commands ------- CD-DRIVER
|
|
V
CD-UNIT
MSCDEX is independent of the Hard, so the Device Driver must
be a standart IO device.
If we want to permorm an action on a CD-ROM we can do
it by diferents ways, using:
0) DOS FUNCTIONS or MSCDEX
1) DIRECTLY TO THE DRIVER
2) ACCESING DIRECTLY TO THE CD-ROM UNIT.
0) MSCDEX
MS-DOS and MSCDEX functions can be reversed and thus be
intercepted easily, just read Part 1 of this Project and
use the next information to develop our own protections/
cracks.
Extracted from Ralf Brown Interrupt List, thanks Ralf.
--------d-2F1500BX0000-----------------------
INT 2F - CD-ROM - INSTALLATION CHECK
AX = 1500h
BX = 0000h
Return: BX = number of CD-ROM drive letters used
CX = starting drive letter (0=A:)
Notes: this installation check DOES NOT follow the format
used by other software
this installation check conflicts with the DOS 4.00
GRAPHICS.COM installation check
BUG: this function may return an incorrect starting drive
letter when INTERLNK is installed
--------d-2F1501-----------------------------
INT 2F - CD-ROM - GET DRIVE DEVICE LIST
AX = 1501h
ES:BX -> buffer to hold drive letter list (5 bytes
per drive letter)
Return: buffer filled, for each drive letter
BYTE subunit number in driver
DWORD address of device driver header (see #1298)
Note: reportedly returns AX=0000h and an invalid address
under Windows95
SeeAlso: AX=1510h
--------d-2F1502-----------------------------
INT 2F - CD-ROM - GET COPYRIGHT FILE NAME
AX = 1502h
ES:BX -> 38-byte buffer for name of copyright file
CX = drive number (0=A:)
Return: CF set if drive is not a CD-ROM drive
AX = 000Fh (invalid drive)
CF clear if successful
SeeAlso: AX=1503h
--------d-2F1503-----------------------------
INT 2F - CD-ROM - GET ABSTRACT FILE NAME
AX = 1503h
ES:BX -> 38-byte buffer for name of abstract file
CX = drive number (0=A:)
Return: CF set if drive is not a CD-ROM drive
AX = 000Fh (invalid drive)
CF clear if successful
SeeAlso: AX=1502h,AX=1504h
--------d-2F1504-----------------------------
INT 2F - CD-ROM - GET BIBLIOGRAPHIC DOC FILE NAME
AX = 1504h
ES:BX -> 38-byte buffer for name of bibliographic
documentation file
CX = drive number (0=A:)
Return: CF set if drive is not a CD-ROM drive
AX = 000Fh (invalid drive)
CF clear if successful
SeeAlso: AX=1502h,AX=1503h
--------d-2F1505-----------------------------
INT 2F - CD-ROM - READ VTOC
AX = 1505h
ES:BX -> 2048-byte buffer
CX = drive number (0=A:)
DX = sector index (0=first volume descriptor,
1=second,...)
Return: CF set on error
AX = error code (15=invalid drive,21=not ready)
CF clear if successful
AX = volume descriptor type (1=standard,
FFh=terminator,0=other)
Note: This function was not supported by Novell DOS 7
NWCDEX prior to the 08/16/94 update
--------d-2F1506-----------------------------
INT 2F - CD-ROM - TURN DEBUGGING ON
AX = 1506h
BX = debugging function to enable
Note: reserved for development
SeeAlso: AX=1507h
--------d-2F1507-----------------------------
INT 2F - CD-ROM - TURN DEBUGGING OFF
AX = 1507h
BX = debugging function to disable
Note: reserved for development
SeeAlso: AX=1506h
--------d-2F1508-----------------------------
INT 2F - CD-ROM - ABSOLUTE DISK READ
AX = 1508h
ES:BX -> buffer
CX = drive number (0=A:)
SI:DI = starting sector number
DX = number of sectors to read
Return: CF set on error
AL = error code(0Fh invalid drive,15h not ready)
CF clear if successful
Note: reportedly returns error 15h (not ready) under
Windows95
SeeAlso: AX=1509h
--------d-2F1509-----------------------------
INT 2F - CD-ROM - ABSOLUTE DISK WRITE
AX = 1509h
ES:BX -> buffer
CX = drive number (0=A:)
SI:DI = starting sector number
DX = number of sectors to write
Note: corresponds to INT 26h and is currently reserved
and nonfunctional
SeeAlso: AX=1508h
--------d-2F150A-----------------------------
INT 2F - CD-ROM - RESERVED
AX = 150Ah
--------d-2F150B-----------------------------
INT 2F - CD-ROM v2.00+ - DRIVE CHECK
AX = 150Bh
CX = drive number (0=A:)
Return: BX = ADADh if MSCDEX.EXE installed
AX = support status
0000h if drive not supported
nonzero if supported
SeeAlso: AX=150Dh
--------d-2F150C-----------------------------
INT 2F - CD-ROM v2.00+ -GET MSCDEX.EXE VERSION (GET VERSION)
AX = 150Ch
Return: BH = major version
BL = minor version
Notes: MSCDEX.EXE versions prior to 2.00 return BX=0000h
Corel's CORELCDX.COM v1.01d returns 2.20
v1.12a returns 2.21
Meridian Data's CDNETEX.EXE returns its own version
Windows95 returns v2.95
SeeAlso: AX=1500h"CD-ROM"
--------d-2F150D-----------------------------
INT 2F - CD-ROM v2.00+ - GET CD-ROM DRIVE LETTERS
AX = 150Dh
ES:BX -> buffer for drive letter list
(1 byte per drive)
Return: buffer filled with drive numbers (0=A:).
Each byte corresponds to the drive in the same
position for function 1501h
SeeAlso: AX=150Bh
--------d-2F150E-----------------------------
INT 2F - CD-ROM v2.00+ -GET/SET VOLUME DESCRIPTOR PREFERENCE
AX = 150Eh
BX = subfunction
00h get preference
DX = 0000h
Return: DX = preference settings
01h set preference
DH = volume descriptor preference
01h = primary volume descriptor
02h = supplementary volume descriptor
DL = supplementary volume descriptor prefer.
01h = shift-Kanji
CX = drive number (0=A:)
Return: CF set on error
AX = error code(15=invalid drive,1=invalid function)
CF clear if successful
--------d-2F150F-----------------------------
INT 2F - CD-ROM v2.00+ - GET DIRECTORY ENTRY
AX = 150Fh
CL = drive number (0=A:)
CH bit 0 = copy flag
clear if direct copy
set if copy to structure which removes
ISO/High Sierra diffs
ES:BX -> ASCIZ path name
SI:DI -> buffer for directory entry
minimum 255 bytes for direct copy
Return: CF set on error
AX = error code
CF clear if successful
AX = disk format (0=High Sierra,1=ISO 9660)
Note: this function was not supported by Novell
DOS 7 NWCDEX prior to the 08/16/94 update
Format of CD-ROM directory entry (direct copy):
Offset Size Description
00h BYTE length of directory entry
01h BYTE length of XAR in Logical Block Numbers
02h DWORD LBN of data, Intel (little-endian) format
06h DWORD LBN of data, Motorola (big-endian) format
0Ah DWORD length of file, Intel format
0Eh DWORD length of file, Motorola format
---High Sierra---
12h 6 BYTEs date and time
18h BYTE bit flags
19h BYTE reserved
---ISO 9660---
12h 7 BYTEs date and time
(seventh byte is offset from GMT in
15-minute increments)
19h BYTE bit flags
---both formats---
1Ah BYTE interleave size
1Bh BYTE interleave skip factor
1Ch WORD volume set sequence number, Intel format
1Eh WORD volume set sequence number, Motorola format
20h BYTE length of file name
21h N BYTEs file name
BYTE (optional) padding if filename is odd length
N BYTEs system data
Format of CD-ROM directory entry (canonicalized):
Offset Size Description
00h BYTE length of XAR in Logical Block Numbers
01h DWORD Logical Block Number of file start
05h WORD size of disk in logical blocks
07h DWORD file length in bytes
0Bh 7 BYTEs date and time
12h BYTE bit flags
13h BYTE interleave size
14h BYTE interleave skip factor
15h WORD volume set sequence number
17h BYTE length of file name
18h 38 BYTEs ASCIZ filename
3Eh WORD file version number
40h BYTE number of bytes of system use data
41h 220 BYTEs system use data
--------d-2F1510-----------------------------
INT 2F - CD-ROM v2.10+ - SEND DEVICE DRIVER REQUEST
AX = 1510h
CX = CD-ROM drive letter (0 = A, 1 = B, etc)
ES:BX -> CD-ROM device driver request header
(see #2251 at AX=0802h)
Note: MSCDEX initializes the device driver request
header's subunit field based on the drive number
specified in CX
BUG: Novell DOS 7 NWCDEX prior to the 12/13/94 update did
not initialize the subunit field
SeeAlso: AX=0802h
--------d-2F15FFBX0000-----------------------
INT 2F - CD-ROM - CORELCDX - INSTALLATION CHECK
AX = 15FFh
BX = 0000h
Return: BX = ABCDh if CORELCDX loaded
Note: Corel's CORELCDX.COM is a replacement for MSCDEX.EXE
it also supports the standard MSCDEX installation
check calls AX=1500h and AX=150Ch
SeeAlso: AX=1500h"CD-ROM",AX=150Ch
1) CD-ROM DEVICE DRIVER
Values for device driver command code:
00h INIT
01h MEDIA CHECK (block devices)
02h BUILD BPB (block devices)
03h IOCTL INPUT
04h INPUT
05h NONDESTRUCTIVE INPUT, NO WAIT (character devices)
06h INPUT STATUS (character devices)
07h INPUT FLUSH (character devices)
08h OUTPUT
09h OUTPUT WITH VERIFY
0Ah OUTPUT STATUS (character devices)
0Bh OUTPUT FLUSH (character devices)
0Ch IOCTL OUTPUT
0Dh (DOS 3.0+) DEVICE OPEN
0Eh (DOS 3.0+) DEVICE CLOSE
0Fh (DOS 3.0+) REMOVABLE MEDIA (block devices)
10h (DOS 3.0+) OUTPUT UNTIL BUSY (character devices)
11h (European MS-DOS 4.0) STOP OUTPUT
12h (European MS-DOS 4.0) RESTART OUTPUT
13h (DOS 3.2+) GENERIC IOCTL
14h unused
15h (European MS-DOS 4.0) RESET UNCERTAIN MEDIA FLAG
16h unused
17h (DOS 3.2+) GET LOGICAL DEVICE
18h (DOS 3.2+) SET LOGICAL DEVICE
19h (DOS 5.0+) CHECK GENERIC IOCTL SUPPORT
80h (CD-ROM) READ LONG
81h (CD-ROM) reserved
82h (CD-ROM) READ LONG PREFETCH
83h (CD-ROM) SEEK
84h (CD-ROM) PLAY AUDIO
85h (CD-ROM) STOP AUDIO
86h (CD-ROM) WRITE LONG
87h (CD-ROM) WRITE LONG VERIFY
88h (CD-ROM) RESUME AUDIO
Bitfields for device request status:
Bit(s) Description
15 error
14-11 reserved
10 ??? set by DOS kernel on entry to some driver calls
9 busy
8 done (may be clear on return under Eur. MS-DOS 4.0)
7-0 error code if bit 15 set
Values for device driver error code:
00h write-protect violation
01h unknown unit
02h drive not ready
03h unknown command
04h CRC error
05h bad drive request structure length
06h seek error
07h unknown media
08h sector not found
09h printer out of paper
0Ah write fault
0Bh read fault
0Ch general failure
0Dh reserved
0Eh (CD-ROM) media unavailable
0Fh invalid disk change
Format of device driver request header:
Offset Size Description (Table 2251)
00h BYTE length of request header
01h BYTE subunit within device driver
02h BYTE command code
03h WORD status (filled in by device driver)
05h 4 BYTEs reserved (unused in DOS 2.x and 3.x)
09h DWORD (European MS-DOS 4.0 only) pointer to next
request header in device's request queue
(other versions) reserved
(unused in DOS 2.x and 3.x)
---command code 00h---
0Dh BYTE (ret) number of units
0Eh DWORD (call) pointer to DOS device helper function
(European MS-DOS 4.0 only)
(call) pointer past end of memory available
to driver (DOS 5+)
(ret) address of first free byte following
driver
12h DWORD (call) pointer to commandline arguments
(ret) pointer to BPB array (block drivers)
or 0000h:0000h (character drivers)
16h BYTE (DOS 3.0+) drive number for first unit of
block driver (0=A)
---European MS-DOS 4.0---
17h DWORD pointer to function to save regs. on stack
---DOS 5+ ---
17h WORD (ret) error-message flag
0001h MS-DOS should display error msg on
init failure
---command code 01h---
0Dh BYTE media descriptor
0Eh BYTE (ret) media status
00h don't know
01h media has not changed
FFh media has been changed
0Fh DWORD (ret, DOS 3.0+) pointer to previous volume
ID if the OPEN/CLOSE/RM bit in device header
is set and disk changed
---command code 02h---
0Dh BYTE media descriptor
0Eh DWORD transfer address
-> scratch sector if NON-IBM FORMAT bit in
device header set
-> first FAT sector otherwise
12h DWORD pointer to BPB (set by driver)
---command codes 03h,0Ch---
0Dh BYTE media descriptor (block devices only)
0Eh DWORD transfer address
12h WORD (call) number of bytes to read/write
(ret) actual number of bytes read or written
---command codes 04h,08h,09h ---
0Dh BYTE media descriptor (block devices only)
0Eh DWORD transfer address
12h WORD byte count (character devices) or sector
count (block devices)
14h WORD starting sector number (block devices only)
16h DWORD (DOS 3.0+) pointer to volume ID if error 0Fh
returned
1Ah DWORD (DOS 4.0+) 32-bit starting sector number
(block devices with device attribute word
bit 1 set only) if starting sector number
above is FFFFh.
---command code 05h---
0Dh BYTE byte read from device if BUSY bit clear
on return
---command codes 06h,07h,0Ah,0Bh,0Dh,0Eh,0Fh---
no further fields
---command code 10h---
0Dh BYTE unused
0Eh DWORD transfer address
12h WORD (call) number of bytes to write
(ret) actual number of bytes written
---command codes 11h,12h---
0Dh BYTE reserved
---command code 15h---
no further fields
---command codes 13h,19h---
0Dh BYTE category code
00h unknown
01h COMn:
03h CON
05h LPTn:
07h mouse (European MS-DOS 4.0)
08h disk
0Fh WORD copy of DS at time of IOCTL call
(apparently unused in DOS 3.3)
SI contents (European MS-DOS 4.0)
11h WORD offset of device driver header
DI contents (European MS-DOS 4.0)
13h DWORD pointer to parameter block from
INT 21/AX=440Ch or AX=440Dh
---command codes 80h,82h---
0Dh BYTE addressing mode
00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD transfer address (ignored for command 82h)
12h WORD number of sectors to read
(if 0 for command 82h, request is an
advisory seek)
14h DWORD starting sector number
logical sector number in HSG mode
frame/second/minute/unused in Red Book mode
(HSG sector = minute * 4500 + second * 75 +
+ frame - 150)
18h BYTE data read mode
00h cooked (2048 bytes per frame)
01h raw (2352 bytes per frame,
including EDC/ECC)
19h BYTE interleave size (number of sectors stored
consecutively)
1Ah BYTE interleave skip factor
(number of sectors between consecutive
portions)
---command code 83h---
0Dh BYTE addressing mode
00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD transfer address (ignored)
12h WORD number of sectors to read (ignored)
14h DWORD starting sector number (see also above)
---command code 84h---
0Dh BYTE addressing mode
00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD starting sector number (see also above)
12h DWORD number of sectors to play
---command codes 85h,88h---
no further fields
---command codes 86h,87h---
0Dh BYTE addressing mode
00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD transfer address (ignored in write mode 0)
12h WORD number of sectors to write
14h DWORD starting sector number (also see above)
18h BYTE write mode
00h mode 0 (write all zeros)
01h mode 1 (default) (2048 bytes per sector)
02h mode 2 form 1 (2048 bytes per sector)
03h mode 2 form 2 (2336 bytes per sector)
19h BYTE interleave size (number of sectors stored
consecutively)
1Ah BYTE interleave skip factor
(number of sectors between consecutive
portions)
Now, we have information enough to write a programm that
opens the CD-ROM (or closes it).
.model large
.stack 100h
blocks struc
lenght_block db 1Dh
disp_num db 0
funct_num db ?
status_word dw 0000
reserv db 8 dup ('?')
media_desc db 0
buffer_off dw 0
buffer_seg dw ?
sec_num dw ?
first_sec dw ?
dummy db 8 dup ('?')
blocks ends
.data
block blocks
Only one commentary about this program because we will use
this info in the next section.
When you call the function 01h of MSCDEX, we get a struct
with the information about our CD driver this info is the
next (every 5 bytes):
offset meanning
00h Subunit number
01h-05h Far ptr to driver
..
..
Now, if we know that a MS-DEVICE-DRIVER has always a 00
offset, we can read the header info on the driver and get
the both FAR_CALLs, just like you can see in the routine
GET_FAR_CALLS.
Driver Header Struct
+00 Far Ptr to next device driver 1 ptr
+04 Device Attribute 1 word
+06 Offset of Strategic Routine 1 word
+08 Offset of Intrrupt Routine 1 word
+0A Device Driver Name 8 byte
+12 Reserver 1 word
+14 First letter assigned 1 byte
+15 Num. of cd-rom unit gestioned 1 byte
This info is used later to 'create' our driver.
2) REVERSING OUR DEVICE DRIVER
This part can be only aplied enterely to the
'CREATIVE CD_ROM UNIT 2x' whose driver is SBIDE.SYS, but you
can extract ideas and then use them on your own drivers.
We will try to find out how our hardware works and how our
controller gets or sends info to the CD_UNIT.
I though (what a stupid idea for my part) that visiting
the Panasonic Web I would obtain technical info about their
products, but no only info about their x24 CD-ROM and some
other things that zoombies search for on the web pages, so
I though that our Linux friends could give us more info, so
I searched for ATAPI.H and SBPCD.H files and I found an important
info for our purposes (thanks friends)
I will first introduce you some aspects of the PIC, BIOS
parameters and ATAPI definitions.
----------P0020003F--------------------------
PORT 0020-003F - PIC 1 - PROGRAMMABLE INTERRUPT CONTROLLER
(8259A)
0020 -W PIC initialization command word ICW1
0020 -W PIC output control word OCW2
0020 -W PIC output control word OCW3
0020 R- PIC interrupt request/in-service registers
after OCW3
request register:
bit 7-0 = 0 no active request for the
corresponding int. line
= 1 active request for
corresponding interrupt line
in-service register:
bit 7-0 = 0 corresponding line not
currently being serviced
= 1 corresponding int. line
currently being serviced
0021 -W PIC ICW2,ICW3,ICW4 immed after ICW1 to 0020
0021 RW PIC master interrupt mask register OCW1
Bitfields for PIC initialization command word ICW1:
Bit(s) Description
7-5 0 (only used in 8080/8085 mode)
4 ICW1 is being issued
3 (LTIM)
=0 edge triggered mode
=1 level triggered mode
2 interrupt vector size
=0 successive interrupt vectors use 8 bytes (8080/5)
=1 successive interrupt vectors use 4 bytes (80x86)
1 (SNGL)
=0 cascade mode
=1 single mode, no ICW3 needed
0 ICW4 needed
Bitfields for PIC initialization command word ICW2:
Bit(s) Description
7-3 address lines A0-A3 of base vector address for PIC
2-0 reserved
Bitfields for PIC initialization command word ICW3:
Bit(s) Description
7-0 =0 slave controller not attached to corresponding
interrupt pin
=1 slave controller attached to corresponding
interrupt pin
Bitfields for PIC initialization command word ICW4:
Bit(s) Description
7-5 reserved (0)
4 running in special fully-nested mode
3-2 mode
0x nonbuffered mode
10 buffered mode/slave
11 buffered mode/master
1 Auto EOI
0 =0 8085 mode
=1 8086/8088 mode
Bitfields for PIC output control word OCW1:
Bit(s) Description
7 disable IRQ7 (parallel printer interrupt)
6 disable IRQ6 (diskette interrupt)
5 disable IRQ5 (fixed disk interrupt)
4 disable IRQ4 (serial port 1 interrupt)
3 disable IRQ3 (serial port 2 interrupt)
2 disable IRQ2 (video interrupt)
1 disable IRQ1 (keyboard, mouse, RTC interrupt)
0 disable IRQ0 (timer interrupt)
Bitfields for PIC output control word OCW2:
Bit(s) Description
7-5 operation
000 rotate in auto EOI mode (clear)
001 (WORD_A) nonspecific EOI
010 (WORD_H) no operation
011 (WORD_B) specific EOI
100 (WORD_F) rotate in auto EOI mode (set)
101 (WORD_C) rotate on nonspecific EOI command
110 (WORD_E) set priority command
111 (WORD_D) rotate on specific EOI command
4-3 reserved (00 - signals OCW2)
2-0 interrupt request to which the command applies
(only used by WORD_B, WORD_D, and WORD_E)
Bitfields for PIC output control word OCW3:
Bit(s) Description
7 reserved (0)
6-5 special mask
0x no operation
10 reset special mask
11 set special mask mode
4-3 reserved (01 - signals OCW3)
2 poll command
1-0 function
0x no operation
10 read interrupt request register on next read
from PORT 0020h
11 read interrupt in-service register on next read
from PORT 0020h
Note: the special mask mode permits all other interrupts
(even those with lower priority) to be processed
while an interrupt is already in service, but will
not reissue an interrupt for a particular IRQ while
it remains in service
----------P00A000AF--------------------------
PORT 00A0-00AF - PIC 2 - PROGRAMMABLE INTERRUPT CONTROLLER
(8259A)
00A0 RW NMI mask register (XT)
bit 7 = 0 disabled
= 1 enabled
00A0 RW PIC 2 same as 0020 for PIC 1
00A1 RW PIC 2 same as 0021 for PIC 1 except for OCW1
Bitfields for PIC2 output control word OCW2:
Bit(s) Description
7 disable IRQ15 (reserved)
6 disable IRQ14 (fixed disk interrupt)
5 disable IRQ13 (coprocessor exception interrupt)
4 disable IRQ12 (mouse interrupt)
3 disable IRQ11 (reserved)
2 disable IRQ10 (reserved)
1 disable IRQ9 (redirect cascade)
0 disable IRQ8 (real-time clock interrupt)
----------M0040006C--------------------------
MEM 0040h:006Ch - TIMER TICKS SINCE MIDNIGHT
Size: DWORD
----------M00400070--------------------------
MEM 0040h:0070h - TIMER OVERFLOW
Size: BYTE
Desc: non-zero if timer has counted past midnight since
last call to INT 1A/AH=00h
Note: the original IBM BIOS, and thus most other BIOSes,
sets this byte to 01h at midnight; a few (such as
the Eagle PC-2) increment it each time midnight is
passed. The former behavior results in lost days
if multiple midnights pass between "get-time" calls
while the machine is powered up.
--------B-M0040008E--------------------------
MEM 0040h:008Eh - FIXED DISK - INTERRUPT CONTROL [not XT]
Size: BYTE
Note: cleared to 00h at start of disk operation, set to
FFh by IRQ14 handler when hard disk controller
completes command
This is our Linux developers friends help.
/*
* Device-independent level for ATAPI drivers.
*
* Copyright (C) 1995 Cronyx Ltd.
* Author Serge Vakulenko,
*
* This software is distributed with NO WARRANTIES, not even
* the implied warranties for MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.
*
* Authors grant any other persons or organizations
* permission to use or modify this software as long as this
* message is kept with the software, all derivative works
* or modified versions.
*
* Version 1.9, Thu Oct 12 15:53:50 MSK 1995
*/
/*
* Disk Controller ATAPI register definitions.
*/
AR_DATA 0x0 /* RW - data register (16 bits) */
AR_ERROR 0x1 /* R - error register */
AR_FEATURES 0x1 /* W - features */
AR_IREASON 0x2 /* RW - interrupt reason */
AR_TAG 0x3 /* - reserved for SAM TAG byte */
AR_CNTLO 0x4 /* RW - byte count, low byte */
AR_CNTHI 0x5 /* RW - byte count, high byte */
AR_DRIVE 0x6 /* RW - drive select */
AR_COMMAND 0x7 /* W - command register */
AR_STATUS 0x7 /* R - immediate status */
/*
* Status register bits
*/
ARS_CHECK 0x01 /* error occured, see sense key/code */
/* bit 0x02 reserved */
ARS_CORR 0x04 /* correctable error occured */
ARS_DRQ 0x08 /* data request / ireason valid */
ARS_DSC 0x10 /* immediate operation completed */
ARS_DF 0x20 /* drive fault */
ARS_DRDY 0x40 /* ready to get command */
ARS_BSY 0x80 /* registers busy */
/* for overlap mode only: */
ARS_SERVICE 0x10 /* service is requested */
ARS_DMARDY 0x20 /* ready to start a DMA transfer */
ARS_BITS "\20\010busy\7ready\6fault\5opdone\4drq\3corr\
1check"
/*
* Error register bits
*/
AER_ILI 0x01 /* illegal length indication */
AER_EOM 0x02 /* end of media detected */
AER_ABRT 0x04 /* command aborted */
AER_MCR 0x08 /* media change requested */
AER_SKEY 0xf0 /* sense key mask */
AER_SK_NO_SENSE 0x00 /* no specific sense key info */
AER_SK_RECOVERED_ERROR 0x10 /* command succeeded, data recovered */
AER_SK_NOT_READY 0x20 /* no access to drive */
AER_SK_MEDIUM_ERROR 0x30 /* non-recovered data error */
AER_SK_HARDWARE_ERROR 0x40 /* non-recoverable hardware failure */
AER_SK_ILLEGAL_REQUEST 0x50 /* invalid command parameter(s) */
AER_SK_UNIT_ATTENTION 0x60 /* media changed */
AER_SK_DATA_PROTECT 0x70 /* reading read-protected sector */
AER_SK_ABORTED_COMMAND 0xb0 /* command aborted, try again */
AER_SK_MISCOMPARE 0xe0 /* data did not match the medium */
AER_BITS "\20\4mchg\3abort\2eom\1ili"
/*
* Feature register bits
*/
ARF_DMA 0x01 /* transfer data via DMA */
ARF_OVERLAP 0x02 /* release the bus until completion */
/*
* Interrupt reason register bits
*/
ARI_CMD 0x01 /* command(1) or data(0) */
ARI_IN 0x02 /* transfer to(1) or from(0) the host */
ARI_RELEASE 0x04 /* bus released until completion */
/*
* Drive register values
*/
ARD_DRIVE0 0xa0 /* drive 0 selected */
ARD_DRIVE1 0xb0 /* drive 1 selected */
/*
* ATA commands
*/
ATAPIC_IDENTIFY 0xa1 /* get drive parameters */
ATAPIC_PACKET 0xa0 /* execute packet command */
/*
* Mandatory packet commands
*/
ATAPI_TEST_UNIT_READY 0x00 /* check if the device is ready */
ATAPI_REQUEST_SENSE 0x03 /* get sense data */
ATAPI_START_STOP 0x1b /* start/stop the media */
ATAPI_PREVENT_ALLOW 0x1e /* prevent/allow media removal */
ATAPI_READ_CAPACITY 0x25 /* get volume capacity */
ATAPI_READ_BIG 0x28 /* read data */
ATAPI_READ_TOC 0x43 /* get table of contents */
ATAPI_READ_SUBCHANNEL 0x42 /* get subchannel info */
ATAPI_MODE_SELECT_BIG 0x55 /* set device parameters */
ATAPI_MODE_SENSE 0x5a /* get device parameters */
ATAPI_PLAY_CD 0xb4 /* universal play command */
/*
* Optional packet commands
*/
ATAPI_PLAY_MSF 0x47 /* play by MSF address */
ATAPI_PAUSE 0x4b /* stop/start audio operation */
/*
* Nonstandard packet commands
*/
ATAPI_PLAY_TRACK 0x48 /* play by track number */
ATAPI_PLAY_BIG 0xa5 /* play by logical block address */
And here more help of out friends:
And now, lets disasembler my SBIDE.SYS file and follow the
code when Function 3 and subfunction 6 is called
(Get CD_Status):
0000 FFFFFFFF BYTE 4 DUP(0ffh)
;Here DOS will put the next driver
;memory location.
0004 00C8 add al , cl
0006 C700D200 mov word ptr [bx+si], 00D2
;C700 is the Est. Routine offset
;D200 is the Int. Routine offset
000A 3132 xor [bp+si], si
000C 3334 xor si, [si]
000E 353637 xor ax, 3736
0011 3800 cmp [bx+si], al
0013 0000 add [bx+si], al
0015 0100 add [bx+si], ax
0017 000000 BYTE 3 DUP(0)
001A B704 mov bh, 04 ;Jump table
001C B704 mov bh, 04
001E B704 mov bh, 04
0020 6802B7 push B702 ;This is jmp for
;function 3. (0268h)
0023 04B7 add al, B7
0025 04B7 add al, B7
0027 048F add al, 8F
0029 04B7 add al, B7
002B 04B7 add al, B7
002D 04B7 add al, B7
002F 04B7 add al, B7
0031 0488 add al, 88
0033 029904A8 add bl , [bx+di+A804]
0037 04B7 add al, B7
0039 04B7 add al, B7
003B 041B add al, 1B
003D 01B7042F add [bx+2F04], si
0041 013D add [di], di
0043 016C01 add [si+01], bp
0046 DE01 fiadd word ptr [bx+di]
0048 B704 mov bh, 04
004A B704 mov bh, 04
004C 40 inc ax
004D 029802A3 add bl , [bx+si+A302]
0051 02B704B7 add dh, [bx+B704]
0055 04C9 add al, C9
0057 02CE add cl , dh
0059 02D3 add dl, bl ;jmp subfunction 6
005B 020E03EB add cl , [EB03] ; (02D3h)
005F 0229 add ch, [bx+di]
0061 036203 add sp, [bp+si+03]
0064 6D insw
0065 037803 add di, [bx+si+03]
0068 83038E add word ptr [bp+di], FF8E
006B 0399030B add bx, [bx+di+0B03]
006F 0439 add al, 39
0071 044D add al, 4D
0073 0462 add al, 62
0075 047B add al, 7B
0077 0485 add al, 85
0079 0400 add al, 00
007B 00000000000000000000 BYTE 10 DUP(0)
0085 00000000000000000000 BYTE 10 DUP(0)
008F 00000000000000000000 BYTE 10 DUP(0)
0099 00000000000000000000 BYTE 10 DUP(0)
00A3 00000000000000000000 BYTE 10 DUP(0)
00AD 00000000000000000000 BYTE 10 DUP(0)
00B7 00000000000000000000 BYTE 10 DUP(0)
00C1 000000000000 BYTE 6 DUP(0)
00C7 2E891E1600 mov cs:[0016], bx ;Strat. Rout.
00CC 2E8C061800 mov cs:[0018], es
00D1 CB retf
00D2 50 push ax ;Interrupt Routine
00D3 53 push bx
00D4 51 push cx
00D5 52 push dx
00D6 56 push si
00D7 57 push di
00D8 55 push bp
00D9 1E push ds
00DA 06 push es
00DB 2EC51E1600 lds bx, cs:[0016]
00E0 8A4701 mov al, [bx+01] ;Subunit number
00E3 98 cbw
00E4 2EA37C00 mov word ptr cs:[007C],ax
;Subunit
00E8 BE1A00 mov si, 001A ;Init table jmp
00EB 8A4702 mov al , [bx+02] ;Funct. number
00EE 3C10 cmp al, 10
00F0 760D jbe 00FF
00F2 3C80 cmp al, 80
00F4 7206 jb 00FC
00F6 2C6F sub al, 6F
00F8 3C19 cmp al, 19
00FA 7603 jbe 00FF
00FC E9B803 jmp 04B7
00FF 98 cbw ;Functions 0-10h
0100 D1E0 shl ax, 01 ; ax=3*2=6h
0102 03F0 add si, ax ;si=1A+6=20h
0104 0BC0 or ax, ax ;is ax=0?
0106 7403 je 010B ;yes jmp init
0108 2EFF24 jmp word ptr cs:[si] ;jmp 0268
010B B001 mov al, 01
010D 2E86067E00 xchg cs:[007E], al
0112 0AC0 or al , al
0114 75F2 jne 0108
0116 EA0B060000 jmp 0000:060B
011B E8BD03 call 04DB
011E 0BC9 or cx, cx
0120 7502 jne 0124
0122 EB05 jmp 0129
.
.
.
0268 BE4E00 mov si, 004E ;jmp base
026B B20F mov dl, 0F
026D C47F0E les di, [bx+0E] ;More_Info_Block
0270 268A05 mov al , es:[di] ;Subfunction 6
0273 47 inc di
0274 38D0 cmp al , dl
0276 7603 jbe 027B
0278 E93C02 jmp 04B7
027B 98 cbw
027C D1E0 shl ax, 01 ax=6*2=0Ch
027E 03F0 add si, ax si=4E+0C=5Ah
0280 2E8B1E7C00 mov bx, cs:[007C] ;Subunit
0285 2EFF24 jmp word ptr cs:[si] ;jmp 2D3h
0288 BE6E00 mov si, 006E
028B B205 mov dl, 05
028D EBDE jmp 026D
028F B80003 mov ax, 0300
0292 E8C302 call 0558
0295 E92902 jmp 04C1
.
.
.
02D3 06 push es
02D4 57 push di
02D5 E8B129 call 2C89
02D8 5F pop di
02D9 07 pop es
02DA 7209 jb 02E5
02DC 268905 mov es:[di], ax
02DF 26895502 mov es:[di+02], dx
02E3 EBAA jmp 028F
02E5 B80281 mov ax, 8102
02E8 E9D901 jmp 04C4
.
.
.
2C89 06 push es
2C8A 33C9 xor cx, cx
2C8C 0E push cs
2C8D 07 pop es
2C8E 53 push bx
2C8F 51 push cx
2C90 B02A mov al, 2A
2C92 2E80BFFA0700 cmp byte ptr cs:[bx+07FA], 00
2C98 7402 je 2C9C ;if subunit=0 =>al=2Ah
2C9A B00F mov al, 0F ;else al=>0Fh
2C9C B420 mov ah, 20 ;Set this values
2C9E BB2829 mov bx, 2928 ;always
2CA1 B91800 mov cx, 0018 ;why???
2CA4 9A20060000 call 0000:0620
;(at cs:620 we have a jmp 085E ==>
Get_CD_Status PROC??)
2CA9 59 pop cx
2CAA 5B pop bx
2CAB 7303 jnb 2CB0 ;any error?
2CAD E9E100 jmp 2D91 ;yes
2CB0 2E80BFFA0700 cmp byte ptr cs:[bx+07FA], 00
2CB6 7502 jne 2CBA
2CB8 EB65 jmp 2D1F
;This part sets the CD_Status bits
;according to the standart order.
2CBA 2EA02A29 mov al, cs:[292A]
2CBE 3C70 cmp al, 70
2CC0 7504 jne 2CC6
2CC2 81C90008 or cx, 0800
2CC6 3C71 cmp al, 71
2CC8 7504 jne 2CCE
2CCA 81C90108 or cx, 0801
2CCE 2EA03429 mov al, cs:[2934]
2CD2 81C90010 or cx, 1000
2CD6 A810 test al, 10
2CD8 7504 jne 2CDE
2CDA 81E1FFEF and cx, EFFF
2CDE 81C90004 or cx, 0400
2CE2 A802 test al, 02
2CE4 7504 jne 2CEA
2CE6 81E1FFFB and cx, FBFF
2CEA 83C910 or cx, 0010
2CED A801 test al, 01
2CEF 7503 jne 2CF4
2CF1 83E1EF and cx, FFEF
2CF4 2EA03529 mov al, cs:[2935]
2CF8 81C90001 or cx, 0100
2CFC A818 test al, 18
2CFE 7504 jne 2D04
2D00 81E1FFFE and cx, FEFF
2D04 83C902 or cx, 0002
2D07 2EF606342980 test byte ptr cs:[2934], 80
2D0D 741C je 2D2B
2D0F 83E1FD and cx, FFFD
2D12 2EF606362902 test byte ptr cs:[2936], 02
2D18 7511 jne 2D2B
2D1A 83C902 or cx, 0002
2D1D EB67 jmp 2D86
2D1F 2EA02A29 mov al, cs:[292A]
2D23 3C70 cmp al, 70
2D25 7504 jne 2D2B
2D27 81C90008 or cx, 0800
2D2B 3C71 cmp al, 71
2D2D 7504 jne 2D33
2D2F 81C90108 or cx, 0801
2D33 2EA03529 mov al, cs:[2935]
2D37 81C90010 or cx, 1000
2D3B A804 test al, 04
2D3D 7504 jne 2D43
2D3F 81E1FFEF and cx, EFFF
2D43 2EA03429 mov al, cs:[2934]
2D47 81C90004 or cx, 0400
2D4B A810 test al, 10
2D4D 7504 jne 2D53
2D4F 81E1FFFB and cx, FBFF
2D53 83C910 or cx, 0010
2D56 A801 test al, 01
2D58 7503 jne 2D5D
2D5A 83E1EF and cx, FFEF
2D5D 2EA03729 mov al, cs:[2937]
2D61 81C90001 or cx, 0100
2D65 A803 test al, 03
2D67 7504 jne 2D6D
2D69 81E1FFFE and cx, FEFF
2D6D 83C902 or cx, 0002
2D70 2EF606362901 test byte ptr cs:[2936], 01
2D76 740E je 2D86
2D78 83E1FD and cx, FFFD
2D7B 2EF606362902 test byte ptr cs:[2936], 02
2D81 7503 jne 2D86
2D83 83C902 or cx, 0002
2D86 81C98402 or cx, 0284
2D8A 8BC1 mov ax, cx ;ax=cd_status word
2D8C 33D2 xor dx, dx
2D8E F8 clc
2D8F 07 pop es
2D90 C3 ret
Let's put a bpx at call interrupt_routine of our program,
Sice must stop at 0001:00D2 (we are executing a get
cd_status command) and stepping a little through the code we
will arrive at the beginning of these function:
Get_CD_Status Proc ??? (Later we will see this is a common
procedure that uses the registers
to perform different operations)
085E FC cld
085F 1E push ds
0860 06 push es
0861 55 push bp
0862 53 push bx
0863 51 push cx
0864 52 push dx
0865 57 push di
0866 56 push si
0867 0E push cs
0868 1F pop ds
0869 E8410E call 16AD ;Save Registers
086C E86E10 call 18DD ;EOI if posible
086F 1E push ds
0870 B84000 mov ax, 0040
0873 8ED8 mov ds, ax
0875 BB8E00 mov bx, 008E
0878 80277F and byte ptr [bx], 7F ;Clears
;byte #7
087B 1F pop ds
087C C606EC0700 mov byte ptr [07EC], 00
0881 C606ED0701 mov byte ptr [07ED], 01 ;Driver
;in use
0886 E87110 call 18FA ;Store IRQ Mask
0889 E8DD0F call 1869 ;Enable CD IRQ
088C C706E8070000 mov word ptr [07E8], 0000
0892 C606C30600 mov byte ptr [06C3], 00
0897 1E push ds
0898 07 pop es
0899 FC cld ;Clears buffer
089A B90C00 mov cx, 000C ;where CD will
089D BF3C06 mov di, 063C ;store it status
08A0 B000 mov al, 00
08A2 F3AA repz stosb
08A4 8B1E7C00 mov bx, [007C]
08A8 D1E3 shl bx, 01
08AA 8B974C07 mov dx, [bx+074C] ;Get IO base
;(3F6h)
08AE B008 mov al, 08
08B0 EE out dx, al ; ????
08B1 8B972C07 mov dx, [bx+072C] ;Get IO base
;(1F6h)
08B5 8A879407 mov al, [bx+0794] ;Get drive
;(B0h)=>1
08B9 EE out dx, al ; Select drive 1
08BA A02706 mov al, [0627] ;Get initial al
(see call 16AD)
08BD D0E0 shl al, 01 ;Function*2
;20h*2=40h
08BF 8D3E1208 lea di, [0812] ;Get Jmp base
08C3 32E4 xor ah, ah ;ah=0
08C5 03F8 add di, ax ;Get Jmp address
;40h+812h=852h
08C7 FF25 jmp word ptr [di] ;Jump 1383h
;this is the point where
;different tasks are done.
08C9 32E4 xor ah, ah
08CB F8 clc
08CC 9C pushf
08CD 50 push ax
08CE E83C10 call 190D ;Restore Old IRQ Mask
08D1 58 pop ax
08D2 9D popf
08D3 2EC606ED0700 mov byte ptr cs:[07ED],00;Driver
;Free
08D9 FB sti
08DA 5E pop si
08DB 5F pop di
08DC 5A pop dx
08DD 59 pop cx
08DE 5B pop bx
08DF 5D pop bp
08E0 07 pop es
08E1 1F pop ds
08E2 CB retf
0842 81 0F E3 08 80 0B E3 08 E3 08 72 13 22 0E 6F 0F
0852 83 13 37 14 77 10 13 15 5A 15 BE 15 FC
^^^^^
Get_CD_Status ENDP ???
Now, we must try to discover what does mean every byte and
what action performs every call, and then, following the
Fravia's advices we will use our Word Processor and we will
replace numbers with letters.
call 16AD ===> Save Registers
16AD 88262706 mov [0627], ah
16B1 A22806 mov byte ptr [0628], al
16B4 882E2906 mov [0629], ch
16B8 880E2A06 mov [062A], cl
16BC 88362B06 mov [062B], dh
16C0 88162C06 mov [062C], dl
16C4 891E2306 mov [0623], bx
16C8 8C062506 mov [0625], es
16CC 893E2F06 mov [062F], di
16D0 89362D06 mov [062D], si
16D4 C3 ret
call 18DD ==> Get PIC Interrupt Service Register
18DD FA cli
18DE 50 push ax
18DF B00B mov al, 0B
18E1 E6A0 out A0, al ;Next read
;give me the
;ISR register
18E3 EB00 jmp 18E5 ;Give time
18E5 EB00 jmp 18E7 ;to PIC
18E7 E4A0 in al, A0 ;Get ISR
18E9 A810 test al, 10 ;Is IRQ.
;in service (CD)
18EB 740A je 18F7 ;Yes, do nothing
18ED B020 mov al, 20 ;EOI
18EF E6A0 out A0, al ;
18F1 EB00 jmp 18F3 ;Give time
18F3 EB00 jmp 18F5 ;to PIC
18F5 E620 out 20, al ;EOI
18F7 58 pop ax
18F8 FB sti
18F9 C3 ret
Bitfields for PIC output control word OCW3:
Bit(s) Description
7 reserved (0)
6-5 special mask
0x no operation
10 reset special mask
11 set special mask mode
4-3 reserved (01 - signals OCW3)
2 poll command
1-0 function
0x no operation
10 read interrupt request register on next read
from PORT 0020h
11 read interrupt in-service register on next read
from PORT 0020h
Remember that 0Bh=00001011b => 0 00 01 0 11
0=Reserved
00=no operation
01=OCW3
0=no polling command
11=read interrupt in service register on next read
of port A0h or 20h.
#10h=00010000==> CD-ROM
Master Slave
bit #0 Timer Real Time Clock
bit #1 Keyboard Free
bit #2 Real Time Clock Free
bit #3 2nd Serial Port Free (usually SB or CD)
bit #4 1st Serial Port Free (usually SB or CD)
bit #5 2nd Paral. Port Math Coprocessor
bit #6 Floppy disk Hard disk
bit #7 1st Paral. Port Free
Bitfields for PIC output control word OCW2:
Bit(s) Description
7-5 operation
000 rotate in auto EOI mode (clear)
001 (WORD_A) nonspecific EOI
010 (WORD_H) no operation
011 (WORD_B) specific EOI
100 (WORD_F) rotate in auto EOI mode (set)
101 (WORD_C) rotate on nonspecific EOI command
110 (WORD_E) set priority command
111 (WORD_D) rotate on specific EOI command
4-3 reserved (00 - signals OCW2)
2-0 interrupt request to which the command applies
(only used by WORD_B, WORD_D, and WORD_E)
And 20h=00100000 ==> 001 00 000
001=nonspecific EOI (end of interruption)
00=OCW2
000=Not used here
call 18FA ==> Get master and slave interrupt mask and stores
them at [6C9] and [6CA]
18FA FA cli
18FB 50 push ax
18FC E421 in al, 21 ;Get Master I.M.
18FE 2EA2C906 mov byte ptr cs:[06C9], al
1902 EB00 jmp 1904 ;Timing
1904 E4A1 in al, A1 ;Get Slave I.M.
1906 2EA2CA06 mov byte ptr cs:[06CA], al
190A 58 pop ax
190B FB sti
190C C3 ret
call 1869 ==> Enable CD interrupts
1869 50 push ax
186A 53 push bx
186B 51 push cx
186C 52 push dx
186D FA cli
186E E4A1 in al, A1 ;Get slave I.M.
1870 8AE0 mov ah, al
1872 EB00 jmp 1874
1874 E421 in al, 21 ;Get master I.M.
1876 2E8B1E7C00 mov bx, cs:[007C] ;Get Subunit
187B D1E3 shl bx, 01 ;Subunit*2
187D 2E8B97CC06 mov dx,cs:[bx+06CC] ;Get IO base
;for this
;subunit
;stored at
;init fase
1882 E81000 call 1895 ;Get CD IRQ
1885 0BC1 or ax, cx ;and enable it
1887 E621 out 21, al ;Set Master IRQ
1889 86E0 xchg al , ah
188B EB00 jmp 188D
188D E6A1 out A1, al ;Set Slave IRQ
188F FB sti
1890 5A pop dx
1891 59 pop cx
1892 5B pop bx
1893 58 pop ax
1894 C3 ret
call 1895 ==> Get CD Interrupt
1895 56 push si
1896 B90400 mov cx, 0004
1899 BEC407 mov si, 07C4
189C 2E3B14 cmp dx, cs:[si] ;dx=1F0h
189F 7408 je 18A9 ;Are equal?
18A1 83C605 add si, 0005 ;No, next posible
;IO base and Int.
18A4 E2F6 loop 189C
18A6 5E pop si
18A7 F9 stc
18A8 C3 ret
18A9 2E8B4C03 mov cx, cs:[si+03] ;Store IRQ
;for CD
18AD 5E pop si
18AE F8 clc
18AF C3 ret
And these are the bytes stored in the file:
(Buffer where the driver will store some important
values).
0623 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0633 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0643 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0653 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0663 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0673 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0683 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0693 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06B3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0691 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
069B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0691 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
069B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
.
.
07C4 F0 01 0E 00 40 70 01 0F 00 80 E8 01 0B 00 08 68
07D4 01 0A 00 04 00 00 00 00 00 00 00 00 00 00 00 00
07E4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0812 0D 0B E3 08 A9 0D E3 08 E3 08 E3 08 81 0C E3 08
0822 34 0E 93 0F 7E 10 9A 10 E8 10 E3 08 E3 08 03 11
call 1895 ==> Restore Old IRQ Mask (see Call 18FA)
190D FA cli
190E 50 push ax
190F 2EA0C906 mov al, cs:[06C9]
1913 E621 out 21, al
1915 EB00 jmp 1917
1917 2EA0CA06 mov al, cs:[06CA]
191B E6A1 out A1, al
191D 58 pop ax
191E FB sti
191F C3 ret
Jmp 1383 ==> Get_Device_Parameters
(action is defined in registers at entry
at address 85Eh)
1383 C706E8070000 mov word ptr [07E8], 0000
;# bytes??
1389 C6063C065A mov byte ptr [063C], 5A
;Mandatory packet
;get device parameters.
138E A02806 mov al, [0628]
1391 A23E06 mov byte ptr [063E], al
1394 A02906 mov al, [0629]
1397 A24306 mov byte ptr [0643], al
139A A02A06 mov al, [062A]
139D A24406 mov byte ptr [0644], al
13A0 8A262906 mov ah, [0629]
13A4 A02A06 mov al, [062A]
13A7 A3E607 mov word ptr [07E6], ax
13AA E86204 call 180F ;Create mandatory
;packet command
13AD E82503 call 16D5 ;Send mandatory packet
13B0 727A jb 142C
13B2 8B3E2306 mov di, [0623]
13B6 8E062506 mov es, [0625]
13BA E8B603 call 1773 ;Is command finished?
13BD 7275 jb 1434
13BF 8B97EC06 mov dx, [bx+06EC] ;dx=1F2h
13C3 EC in al, dx ;Get Int. reason
13C4 3C02 cmp al, 02 ;Was int. caused by
; a transfer?
13C6 7403 je 13CB
13C8 E98AF6 jmp 0A55
13CB 8B973C07 mov dx, [bx+073C] ;dx=1F7h
13CF EC in al, dx
13D0 A801 test al, 01 ;Any error?
13D2 7403 je 13D7
13D4 E929F5 jmp 0900
13D7 8B971C07 mov dx, [bx+071C] ;dx=1F5h
13DB EC in al, dx ;Get #bytes to receive
13DC 8AE0 mov ah, al
13DE 4A dec dx
13DF EC in al, dx
13E0 8BC8 mov cx, ax
13E2 010EE807 add [07E8], cx
13E6 FC cld
13E7 D1E9 shr cx, 01 ;bytes->words
13E9 8B97CC06 mov dx, [bx+06CC] ;Get base 3F7h
13ED F36D repz insw ;Get CD_Status bytes
13EF A1E807 mov ax, word ptr [07E8]
13F2 3906E607 cmp [07E6], ax ;correct #bytes
;received?
13F6 75C2 jne 13BA
13F8 E87803 call 1773 ;Dis/Enable CD irq
13FB 7237 jb 1434
13FD 53 push bx
13FE D1EB shr bx, 01
1400 80BFFA0700 cmp byte ptr [bx+07FA], 00
1405 5B pop bx
1406 740C je 1414
1408 8B973C07 mov dx, [bx+073C]
140C EC in al, dx
140D A808 test al, 08
140F 740F je 1420
1411 E941F6 jmp 0A55
1414 8B97EC06 mov dx, [bx+06EC]
1418 EC in al, dx
1419 3C03 cmp al, 03
141B 7403 je 1420
141D E935F6 jmp 0A55
1420 8B973C07 mov dx, [bx+073C]
1424 EC in al, dx
1425 A801 test al, 01
1427 7408 je 1431
1429 E9D4F4 jmp 0900
142C 7406 je 1434
142E E9BAF4 jmp 08EB
1431 E995F4 jmp 08C9
1434 E9BCF4 jmp 08F3
call 180F ==> Create a mandatory packet command (M.P.C.) and
store it at 648h.
180F FC cld
1810 BF4806 mov di, 0648 ;M.P.C.
1813 0E push cs
1814 07 pop es
1815 B000 mov al, 00
1817 AA stosb
1818 B000 mov al, 00
181A AA stosb
181B AA stosb
181C A1E607 mov ax, word ptr [07E6]
181F AA stosb
1820 86E0 xchg al , ah
1822 AA stosb
1823 8A879407 mov al ,[bx+0794] ;Drive (B0h=1)
1827 AA stosb
1828 B0A0 mov al, A0 ;Command (A0h=execute
;M.P.C.)
182A AA stosb
182B C3 ret
The result of this action is:
0648 00 00 00 ?? ?? B0 A0
where ???? is stored at [7E6] and you could see how [7E6] is
a copy of the memory location word [629]==> CX at entry (see
call 16AD).
call 16D5 ==> Send Mandatory packet
16D5 8B1E7C00 mov bx, [007C];get subunit
16D9 D1E3 shl bx, 01
16DB E8DD00 call 17BB ;Is drive busy?
16DE 7244 jb 1724 ;Any Error?
16E0 E84901 call 182C ;Initialize driver and
;prepare it to receive
;the M.P.C.
16E3 80BFA40700 cmp byte ptr [bx+07A4], 00
16E8 7502 jne 16EC
16EA EB19 jmp 1705
16EC E88400 call 1773 ;Is command finished?
16EF 7233 jb 1724
16F1 8B97EC06 mov dx, [bx+06EC]
16F5 EC in al, dx
16F6 3C01 cmp al, 01
16F8 752E jne 1728
16FA 8B973C07 mov dx, [bx+073C]
16FE EC in al, dx
16FF A808 test al, 08
1701 7425 je 1728
1703 EB05 jmp 170A
1705 E82400 call 172C ;Prepared to data
;request?
1708 721A jb 1724
170A 8B973C07 mov dx, [bx+073C]
170E EC in al, dx
170F A880 test al, 80 ;Is busy?
1711 7402 je 1715 ;No, send
1713 EBF5 jmp 170A ;Yes, try again
1715 FC cld
1716 BE3C06 mov si, 063C ;M.P.C. add.
1719 B90600 mov cx, 0006 ;Send 0Ch
;bytes
;(63Ch-647h)
171C 8B97CC06 mov dx, [bx+06CC];dx=1F0h
1720 F3 repz
1721 6F outsw
1722 F8 clc
1723 C3 ret
1724 32E4 xor ah, ah
1726 F9 stc ;Return with error
1727 C3 ret
1728 0BD2 or dx, dx
172A F9 stc
172B C3 ret
call 17BB ==> Is drive busy?
17BB C706C4060200 mov word ptr [06C4], 0002
17C1 2E803ECB0688 cmp byte ptr cs:[06CB], 88
;at init fase, we can set the drq
;type, on depending of this we set
;different timeouts values (I need
;more info of this phase)
17C7 7406 je 17CF
17C9 C706C406B400 mov word ptr [06C4],00B4 ;timeout
;value
17CF E8F101 call 19C3 ;Set timeout
17D2 E81202 call 19E7 ;Is timeout finished?
17D5 740B je 17E2 ;Yes, return with error
;we are tired of waiting
17D7 8B973C07 mov dx, [bx+073C] ;Get inmediate
17DB EC in al, dx ;status
17DC A880 test al, 80 ;Is busy?
17DE 75F2 jne 17D2 ;Yes, give it more time
17E0 F8 clc
17E1 C3 ret
17E2 F9 stc
17E3 C3 ret
call 19C3 ==> Set Timeout (get bios ticks counter, adds
the timeout value and stores it at
[6C4])
19C3 9C pushf
19C4 50 push ax
19C5 53 push bx
19C6 1E push ds
19C7 BB4000 mov bx, 0040
19CA 8EDB mov ds, bx
19CC BB6C00 mov bx, 006C ;Bios ticks
;count
19CF 8B07 mov ax, [bx]
19D1 8B5F02 mov bx, [bx+02]
19D4 1F pop ds
19D5 891EC606 mov [06C6], bx
19D9 0106C406 add [06C4], ax
19DD 7304 jnb 19E3
19DF FF06C606 inc word ptr [06C6]
19E3 5B pop bx
19E4 58 pop ax
19E5 9D popf
19E6 C3 ret
call 19E7 ==> Is timeout finished? (compare Bios ticks
counter with previously stored value)
19E7 50 push ax
19E8 53 push bx
19E9 1E push ds
19EA B84000 mov ax, 0040
19ED 8ED8 mov ds, ax
19EF BB6C00 mov bx, 006C
19F2 8B07 mov ax, [bx]
19F4 8B5F02 mov bx, [bx+02]
19F7 1F pop ds
19F8 3B1EC606 cmp bx, [06C6]
19FC 7208 jb 1A06
19FE 3B06C406 cmp ax, [06C4]
1A02 7202 jb 1A06
1A04 33C0 xor ax, ax ;Time finished
1A06 5B pop bx
1A07 58 pop ax
1A08 C3 ret
call 1773 ==> Is command finished?
1773 53 push bx
1774 E8C600 call 183D ;Disable CD irq
1777 C706C406B400 mov word ptr [06C4], 00B4
177D E84302 call 19C3 ;Set timeout
1780 E86402 call 19E7 ;Is timeout finished?
1783 7430 je 17B5
1785 F606EC0701 test byte ptr [07EC], 01
178A 751E jne 17AA
178C E82101 call 18B0 ;Get CD irq number
178F 3C0E cmp al, 0E ;Is 0Eh?
1791 75ED jne 1780
1793 1E push ds
1794 B84000 mov ax, 0040
1797 8ED8 mov ds, ax
1799 BB8E00 mov bx, 008E
179C F60780 test byte ptr [bx], 80
;irq sets this bit when the
;command is finished
179F 7406 je 17A7
17A1 80277F and byte ptr [bx], 7F ;Clear it
;for future uses.
17A4 1F pop ds
17A5 EB03 jmp 17AA
17A7 1F pop ds
17A8 EBD6 jmp 1780 ;Give it more time
;to end the command
17AA C606EC0700 mov byte ptr [07EC], 00
17AF E8B700 call 1869 ;Enable CD irq
17B2 5B pop bx
17B3 F8 clc ;No error returned
17B4 C3 ret
17B5 E8B100 call 1869 ;Enable CD irq
17B8 5B pop bx
17B9 F9 stc ;Error returned
17BA C3 ret
call 183D ==> Disable CD irq
183D 50 push ax
183E 53 push bx
183F 51 push cx
1840 52 push dx
1841 FA cli
1842 E4A1 in al, A1
1844 8AE0 mov ah, al
1846 EB00 jmp 1848
1848 E421 in al, 21
184A 8B1E7C00 mov bx, [007C] ;subunit
184E D1E3 shl bx, 01
1850 8B97CC06 mov dx, [bx+06CC]
1854 E83E00 call 1895 ;Get CD irq
1857 F7D1 not cx
1859 23C1 and ax, cx ;and clear it
185B E621 out 21, al ;send irq mask
185D 86E0 xchg al , ah
185F EB00 jmp 1861
1861 E6A1 out A1, al
1863 FB sti
1864 5A pop dx
1865 59 pop cx
1866 5B pop bx
1867 58 pop ax
1868 C3 ret
call 18D0 ==> Get CD irq number
18B0 56 push si
18B1 53 push bx
18B2 51 push cx
18B3 52 push dx
18B4 2E8B1E7C00 mov bx, cs:[007C] ;Subunit
18B9 D1E3 shl bx, 01
18BB 2E8B97CC06 mov dx, cs:[bx+06CC]
18C0 B90400 mov cx, 0004
18C3 BEC407 mov si, 07C4
18C6 2E3B14 cmp dx, cs:[si]
18C9 7408 je 18D3
18CB 83C605 add si, 0005
18CE E2F6 loop 18C6
18D0 F9 stc
18D1 EB05 jmp 18D8
18D3 2E8A4402 mov al , cs:[si+02] ;return irq
;number
18D7 F8 clc
18D8 5A pop dx
18D9 59 pop cx
18DA 5B pop bx
18DB 5E pop si
18DC C3 ret
call 182C ==> Prepare drive to receive the M.P.C.
182C FC cld
182D BE4806 mov si, 0648
1830 8B97DC06 mov dx, [bx+06DC]
1834 B90700 mov cx, 0007
1837 AC lodsb
1838 EE out dx, al
1839 42 inc dx
183A E2FB loop 1837
183C C3 ret
call 172Ch ==> Prepared to data request?
172C 803E3C0612 cmp byte ptr [063C], 12
;Was command 12h?
;What is this command????
1731 750E jne 1741
1733 C706C4060200 mov word ptr [06C4], 0002
1739 E88702 call 19C3
173C E8A802 call 19E7
173F 75FB jne 173C
1741 8B974C07 mov dx, [bx+074C]
1745 E87300 call 17BB ;Is drive busy?
1748 7225 jb 176F
174A C706C4060200 mov word ptr [06C4], 0002
1750 2E803ECB0688 cmp byte ptr cs:[06CB], 88
1756 7406 je 175E
1758 C706C406B400 mov word ptr [06C4], 00B4
175E E86202 call 19C3 ;Set timeout
1761 E88302 call 19E7 ;Is timeout finished?
1764 7409 je 176F
1766 EC in al, dx ;Get inmediate status
1767 2488 and al, 88
1769 3C08 cmp al, 08 ;Prepared for data
;request?
176B 7404 je 1771
176D EBF2 jmp 1761
176F F9 stc
1770 C3 ret
1771 F8 clc
1772 C3 ret
Well, sorry I know this doc is very disordered, but you can
print it and so it will be easier to understand.
The conclusions we can extract of this is how a CD_UNIT,
works and we can find some M.P.C. we can use either under
W95 (this will be the next step of this project).
The execution flow is:
*Get function to perform.
*Prepare drive to send M.P.C.
*Create the M.P.C. for this function
*Send M.P.C.
*Get Data sent by the drive.
Obviously we must check the drive status between steps,
to be sure we can send/receive correctly the data.
So we will try to find out all the M.P.C., and here we have
again the invaluable help of Linux developers.
This is part of the sbpcd.h file.
all numbers (lba, msf-bin, msf-bcd, counts) to transfer high byte first
mnemo 7-byte command #bytes response (r0...rn)
________ ____________________ ____
Read Status:
status: 81. (1) one-byte command, gives the main
status byte
Read Error:
check1: 82 00 00 00 00 00 00. (6) r1: audio status
Read Packet:
check2: 8e xx 00 00 00 00 00. (xx) gets xx bytes response, relating
to commands 01 04 05 07 08 09
Play Audio:
play: 0a ll-bb-aa nn-nn-nn. (0) play audio, ll-bb-aa: starting block (lba),
nn-nn-nn: #blocks
Play Audio MSF:
0b mm-ss-ff mm-ss-ff (0) play audio from/to
Play Audio Track/Index:
0c ...
Pause/Resume:
pause: 8d pr 00 00 00 00 00. (0) pause (pr=00)
resume (pr=80) audio playing
Mode Select:
84 00 nn-nn ??-?? 00 (0) nn-nn: 2048 or 2340
possibly defines transfer size
set_vol: 84 83 00 00 sw le 00. (0) sw(itch): lrxxxxxx (off=1)
le(vel): min=0, max=FF, else half
(firmware 2.11)
Mode Sense:
get_vol: 85 03 00 00 00 00 00. (2) tell current audio volume setting
Read Disc Information:
tocdesc: 8b 00 00 00 00 00 00. (6) read the toc descriptor ("msf-bin"-format)
Read TOC:
tocent: 8c fl nn 00 00 00 00. (8) read toc entry #nn
(fl=0:"lba"-, =2:"msf-bin"-format)
Read Capacity:
capacit: 88 00 00 00 00 00 00. (5) "read CD-ROM capacity"
Read Path Check:
ping: 00 00 00 00 00 00 00. (2) r0=AA, r1=55
("ping" if the drive is connected)
Read Drive Version:
ident: 83 00 00 00 00 00 00. (12) gives "MATSHITAn.nn"
(n.nn = 2.01, 2.11., 3.00, ...)
Seek:
seek: 01 00 ll-bb-aa 00 00. (0)
seek: 01 02 mm-ss-ff 00 00. (0)
Read Data:
read: 02 xx-xx-xx nn-nn fl. (??) read nn-nn blocks of 2048 bytes,
starting at block xx-xx-xx
fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
Read XA-Data:
read: 03 xx-xx-xx nn-nn fl. (??) read nn-nn blocks of 2340 bytes,
starting at block xx-xx-xx
fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
Read SUB_Q:
89 fl 00 00 00 00 00. (13) r0: audio status, r4-r7: lba/msf,
fl=0: "lba", fl=2: "msf"
Read Disc Code:
8a 00 00 00 00 00 00. (14) possibly extended "check condition"-info
Read Header:
04 00 ll-bb-aa 00 00. (0) 4 bytes response with "check2"
04 02 mm-ss-ff 00 00. (0) 4 bytes response with "check2"
Spin Up:
05 00 ll-bb-aa 00 00. (0) possibly implies a "seek"
Spin Down:
06 ...
Diagnostic:
07 00 ll-bb-aa 00 00. (2) 2 bytes response with "check2"
07 02 mm-ss-ff 00 00. (2) 2 bytes response with "check2"
Read UPC:
08 00 ll-bb-aa 00 00. (16)
08 02 mm-ss-ff 00 00. (16)
Read ISRC:
09 00 ll-bb-aa 00 00. (15) 15 bytes response with "check2"
09 02 mm-ss-ff 00 00. (15) 15 bytes response with "check2"
Set XA Parameter:
86 ...
Read XA Parameter:
87 ...
==============================================================================
============================================================================*/
/*
* commands
*
* CR-52x: CMD0_
* CR-56x: CMD1_
* CD200: CMD2_ <== This is my CD model. * LCS-7260: CMDL_ * TEAC CD-55A: CMDT_ * ECS-AT: CMDV_ */ #define CMD1_RESET 0x0a #define CMD2_RESET 0x01 #define CMDT_RESET 0xc0 #define CMD1_LOCK_CTL 0x0c #define CMD2_LOCK_CTL 0x1e #define CMDT_LOCK_CTL CMD2_LOCK_CTL #define CMDL_LOCK_CTL 0x0e #define CMDV_LOCK_CTL CMDL_LOCK_CTL #define CMD1_TRAY_CTL 0x07 #define CMD2_TRAY_CTL 0x1b #define CMDT_TRAY_CTL CMD2_TRAY_CTL #define CMDL_TRAY_CTL 0x0d #define CMDV_TRAY_CTL CMDL_TRAY_CTL #define CMD1_MULTISESS 0x8d #define CMDL_MULTISESS 0x8c #define CMDV_MULTISESS CMDL_MULTISESS #define CMD1_SUBCHANINF 0x11 #define CMD2_SUBCHANINF 0x?? #define CMD1_ABORT 0x08 #define CMD2_ABORT 0x08 #define CMDT_ABORT 0x08 #define CMD2_x02 0x02 #define CMD2_SETSPEED 0xda #define CMD0_PATH_CHECK 0x00 #define CMD1_PATH_CHECK 0x??? #define CMD2_PATH_CHECK 0x??? #define CMDT_PATH_CHECK 0x??? #define CMDL_PATH_CHECK CMD0_PATH_CHECK #define CMDV_PATH_CHECK CMD0_PATH_CHECK #define CMD0_SEEK 0x01 #define CMD1_SEEK CMD0_SEEK #define CMD2_SEEK 0x2b #define CMDT_SEEK CMD2_SEEK #define CMDL_SEEK CMD0_SEEK #define CMDV_SEEK CMD0_SEEK #define CMD0_READ 0x02 #define CMD1_READ 0x10 #define CMD2_READ 0x28 #define CMDT_READ CMD2_READ #define CMDL_READ CMD0_READ #define CMDV_READ CMD0_READ #define CMD0_READ_XA 0x03 #define CMD2_READ_XA 0xd4 #define CMD2_READ_XA2 0xd5 #define CMDL_READ_XA CMD0_READ_XA /* really ?? */ #define CMDV_READ_XA CMD0_READ_XA #define CMD0_READ_HEAD 0x04 #define CMD0_SPINUP 0x05 #define CMD1_SPINUP 0x02 #define CMD2_SPINUP CMD2_TRAY_CTL #define CMDL_SPINUP CMD0_SPINUP #define CMDV_SPINUP CMD0_SPINUP #define CMD0_SPINDOWN 0x06 /* really??? */ #define CMD1_SPINDOWN 0x06 #define CMD2_SPINDOWN CMD2_TRAY_CTL #define CMDL_SPINDOWN 0x0d #define CMDV_SPINDOWN CMD0_SPINDOWN #define CMD0_DIAG 0x07 #define CMD0_READ_UPC 0x08 #define CMD1_READ_UPC 0x88 #define CMD2_READ_UPC 0x??? #define CMDL_READ_UPC CMD0_READ_UPC #define CMDV_READ_UPC 0x8f #define CMD0_READ_ISRC 0x09 #define CMD0_PLAY 0x0a #define CMD1_PLAY 0x??? #define CMD2_PLAY 0x??? #define CMDL_PLAY CMD0_PLAY #define CMDV_PLAY CMD0_PLAY #define CMD0_PLAY_MSF 0x0b #define CMD1_PLAY_MSF 0x0e #define CMD2_PLAY_MSF 0x47 #define CMDT_PLAY_MSF CMD2_PLAY_MSF #define CMDL_PLAY_MSF 0x??? #define CMD0_PLAY_TI 0x0c #define CMD1_PLAY_TI 0x0f #define CMD0_STATUS 0x81 #define CMD1_STATUS 0x05 #define CMD2_STATUS 0x00 #define CMDT_STATUS CMD2_STATUS #define CMDL_STATUS CMD0_STATUS #define CMDV_STATUS CMD0_STATUS #define CMD2_SEEK_LEADIN 0x00 #define CMD0_READ_ERR 0x82 #define CMD1_READ_ERR CMD0_READ_ERR #define CMD2_READ_ERR 0x03 #define CMDT_READ_ERR CMD2_READ_ERR /* get audio status */ #define CMDL_READ_ERR CMD0_READ_ERR #define CMDV_READ_ERR CMD0_READ_ERR #define CMD0_READ_VER 0x83 #define CMD1_READ_VER CMD0_READ_VER #define CMD2_READ_VER 0x12 #define CMDT_READ_VER CMD2_READ_VER /* really ?? */ #define CMDL_READ_VER CMD0_READ_VER #define CMDV_READ_VER CMD0_READ_VER #define CMD0_SETMODE 0x84 #define CMD1_SETMODE 0x09 #define CMD2_SETMODE 0x55 #define CMDT_SETMODE CMD2_SETMODE #define CMDL_SETMODE CMD0_SETMODE #define CMD0_GETMODE 0x85 #define CMD1_GETMODE 0x84 #define CMD2_GETMODE 0x5a #define CMDT_GETMODE CMD2_GETMODE #define CMDL_GETMODE CMD0_GETMODE #define CMD0_SET_XA 0x86 #define CMD0_GET_XA 0x87 #define CMD0_CAPACITY 0x88 #define CMD1_CAPACITY 0x85 #define CMD2_CAPACITY 0x25 #define CMDL_CAPACITY CMD0_CAPACITY /* missing in some firmware versions */ #define CMD0_READSUBQ 0x89 #define CMD1_READSUBQ 0x87 #define CMD2_READSUBQ 0x42 #define CMDT_READSUBQ CMD2_READSUBQ #define CMDL_READSUBQ CMD0_READSUBQ #define CMDV_READSUBQ CMD0_READSUBQ #define CMD0_DISKCODE 0x8a #define CMD0_DISKINFO 0x8b #define CMD1_DISKINFO CMD0_DISKINFO #define CMD2_DISKINFO 0x43 #define CMDT_DISKINFO CMD2_DISKINFO #define CMDL_DISKINFO CMD0_DISKINFO #define CMDV_DISKINFO CMD0_DISKINFO #define CMD0_READTOC 0x8c #define CMD1_READTOC CMD0_READTOC #define CMD2_READTOC 0x??? #define CMDL_READTOC CMD0_READTOC #define CMDV_READTOC CMD0_READTOC #define CMD0_PAU_RES 0x8d #define CMD1_PAU_RES 0x0d #define CMD2_PAU_RES 0x4b #define CMDT_PAUSE CMD2_PAU_RES #define CMDL_PAU_RES CMD0_PAU_RES #define CMDV_PAUSE CMD0_PAU_RES #define CMD0_PACKET 0x8e #define CMD1_PACKET CMD0_PACKET #define CMD2_PACKET 0x??? #define CMDL_PACKET CMD0_PACKET #define CMDV_PACKET 0x??? And more defines: /* * bits of flags_cmd_out: */ #define f_respo3 0x100 #define f_putcmd 0x80 #define f_respo2 0x40 #define f_lopsta 0x20 #define f_getsta 0x10 #define f_ResponseStatus 0x08 #define f_obey_p_check 0x04 #define f_bit1 0x02 #define f_wait_if_busy 0x01 /* * diskstate_flags: */ #define x80_bit 0x80 #define upc_bit 0x40 #define volume_bit 0x20 #define toc_bit 0x10 #define multisession_bit 0x08 #define cd_size_bit 0x04 #define subq_bit 0x02 #define frame_size_bit 0x01 /* * the status_bits variable */ #define p_success 0x100 #define p_door_closed 0x80 #define p_caddy_in 0x40 #define p_spinning 0x20 #define p_check 0x10 #define p_busy_new 0x08 #define p_door_locked 0x04 #define p_disk_ok 0x01 With this info, we can work developing our own driver, with it we can control all, even we can create a virtual CD on any directory of your hard disk, simply returning the info that the program demands. W95 is the same, go to the iosubsys directory and find the vxd file that handles the CD (I'm working on it at this time). Comments, addings and corrections are welcomed (and needed) +Rcg 1997
(c) +Rcg, 1997. All rights reversed.
You are deep inside fravia's page of reverse engineering,
choose your way out:
Back to Project 4
homepage
links
anonymity
+ORC
students' essays
academy database
tools
cocktails
antismut CGI-scripts
search_forms
mail_fravia
Is reverse engineering illegal?