воскресенье, 18 января 2009 г.

Удачная попытка доступа к лазерному диску на низком уровне



Created with colorer-take5 library. Type 'asm'



.386p

ideal

model tiny

; CD-DA reading (C)1999 Alex Derbeev <derbeev2@tut.by, zedplace@mail.ru>

cd_let = 'z' ; cd-rom drive letter (lowercase)

count = 26 ; number of audio sectors per call

; (max=27 coz RM segm=64k)

st_sec = 30;256875;230004;230004+9000 ; first sector of the track

en_sec = 1000;21881/2;320248;248489;230004+9000+750;248489 ; last sector of the track

_INIT_ = 0 ; initialize CD-ROM thru the port

_WAVE_ = 0 ; output format = wav | raw

__16__ = 1 ; word\byte per sample

_DMIX_ = 0 ; downmix stereo

_SWAP_ = 0 ; swap channels



;secsiz = 2048 ; sector size in bytes

secsiz = 2352 ; sector size in bytes

; 2048-cooked,2352-raw

cd_dev = 0c903h ; cd driver segment

;---------------------------------------

macro write Mess_Offs

mov ah,9

lea dx,[Mess_Offs]

int 21h

endm



codeseg

org 100h

start:

mov ax,1500h ; count cd drive letters

xor bx,bx

int 2fh

or bx,bx

jz no_cd

mov ax,150ch

xor bx,bx

int 2fh

cmp bx,20ah ; must be 2.10+

jb no_cd



if _INIT_ gt 0



mov eax,cr0

test al,10h

jz @@r_passed ; cannot reset under win



write m_init



mov al,8 ; 'drive reset`

ide_port=170h ; secondary master

; 1f0h=pm,170h=sm,1e8h=ps,168h

mov dx,ide_port+7 ; status/cmd reg

out dx,al



mov ax,8301h ; cancel prev wait

int 15h

mov ax,8300h ; set wait interval

mov cx,0002dh

mov dx,0c6c0h

lea bx,[flag]

int 15h

mov dx,ide_port+7 ; status reg (read)

@@wait: in al,dx

jmp $+2 ; what for in cycle?

and al,80h

xor al,80h

or al,[flag]

jz @@wait ; cd busy & still waiting

mov ax,8301h

int 15h

in al,dx

test al,80h

jnz fail_init



write m_init_ok



@@r_passed:

endif

push cd_dev

pop es

mov ax,[es:6]

mov [word strat],ax

mov ax,[es:8]

mov [word interr],ax

mov [word transf],offset buffer

mov [word transf+2],ds



push ds

pop es



if _INIT_ eq 0

mov [reset_adr+2],ds

lea bx,[IOCTLO] ; es:bx - request

mov ax,1510h ; send device driver request

mov cx,cd_let-'a'

int 2fh

test [status_],8000h

jnz not_ready

endif



mov ah,3ch ; create

lea dx,[filename]

mov cx,20h ; attr=archive

int 21h

jc io_error

mov bp,ax



if _WAVE_ eq 1

mov ah,40h ; write wav header

mov bx,bp

mov cx,wav_hdr_sz

lea dx,[Wav_Hdr]

int 21h

jc io_error

endif

again: mov cx,7

@@1:

push cx

lea bx,[requ] ; es:bx - request

mov [status],0

call [strat]

call [interr]

;mov ax,1510h ; send device driver request

;mov cx,cd_let-'a'

;int 2fh

test [status],8000h

pop cx

loopnz @@1

jnz error



mov bx,bp

mov ax,[sec_count]

mov cx,secsiz

mul cx

if _SWAP_ eq 1

if _DMIX_ eq 0

pusha

lea di,[buffer]

shr ax,2

xchg cx,ax

   @@swap: rol [dword di],16

add di,4

loop @@swap

popa

endif

endif

if __16__ eq 0 ;convert word resolution to 8bit

pushad

lea di,[buffer]

mov si,di

shr ax,1

xchg cx,ax



fstcw [cw]

mov ax,0f3ffh

fwait

mov dx,[cw]

and ax,dx

or ah,8

mov [cw],ax

fldcw [cw]



@@mix_res: fld [mix_value]

cmp [word si],-32768

jne @@next

mov ah,2

mov dl,7

int 21h

@@next:

fimul [word si]

;---------------------------------------------------

frndint

;---------------------------------------------------

fistp [word si]

mov ax,[si]

add al,80h

mov [di],al

inc di

add si,2

loop @@mix_res



mov [cw],dx

fldcw [cw]

popad

shr ax,1

endif

if _DMIX_ eq 1 ;downmixing

pushad

lea di,[buffer]

mov si,di

shr ax,2

xchg cx,ax

@@mix: movsx eax,[word si] ;

movsx edx,[word si+2] ;

add eax,edx ;

sar eax,1 ; signed - just to b sure

mov [di],ax ;

add di,2

add si,4

loop @@mix

popad

shr ax,1

endif

mov cx,ax

push cx

movzx eax,ax

add [total],eax

lea dx,[buffer];+16]

mov ah,40h ; write file

pusha ;-)



movzx eax,[sec_count]

add [sector],eax

cmp [sector],en_sec

ja _close

add eax,[sector]

cmp eax,en_sec+1

jbe again_

mov [sec_count],1

jmp again_

again_:

mov ax,[sec_count]

;mov [sec_count_],ax

mov eax,[sector]

mov [sector_],eax

lea bx,[read_pref] ; es:bx - request

mov ax,1510h ; send device driver request

mov cx,cd_let-'a'

;int 2fh

;test [phuk],8000h

;jnz error



popa

int 21h

pop cx



jc _error

cmp cx,ax

jne _error

call convert ; print KB ready

jmp again



_error:

mov ah,68h ; flush cached data

mov bx,bp

int 21h

jc io_error

mov ah,13 ; reset disk

int 21h

write m_full



_close:

mov ah,3eh ; close

mov bx,bp

int 21h

jc io_error



write m_ok



jmp quit



no_cd:

lea dx,[m_nocd]

jmp quit_msg

fail_init:

write m_init_fail

not_ready:

lea dx,[m_ready]

jmp quit_msg

io_error:

lea dx,[m_io]

jmp quit_msg

error:

write m_crash

movzx bx,[byte status]

cmp bl,0fh

jbe @@1

cmp bl,0fdh

jb @@2

sub bl,0edh

@@1: add bx,bx

mov dx,[cd_errors+bx]

int 21h

@@2: write new_line

jmp quit

quit_msg:

mov ah,9

int 21h

quit:

push 0

pop ds

mov ax,[41ah]

mov [41ch],ax

jmp $+2



int 20h

;-------------------------------------------------------------------------------

convert:

pushad

lea di,[ready+6]

mov eax,[total]

lea ecx,[10]

shr eax,cl

@@1: sub edx,edx

or eax,eax

jz @@2

div ecx

xchg eax,edx

add al,'0'

mov [di],al

dec di

xchg eax,edx

jmp @@1

@@2: mov ah,3

mov bh,0

int 10h

mov ah,2

mov bh,0

mov dl,0

int 10h

write ready

popad

ret

;-------------------------------------------------------------------------------

flag db 0

total dd 0

ready db 7 dup (' ')," KB ...OK$"

if _WAVE_ eq 1

filename db ".\cd_data.wav",0 ; Microsoft RIFF Wave

else

filename db ".\cd_data.raw",0 ; raw PCM audio data file

endif

m_init db "Initializing...$"

m_init_ok db "OK",0dh,0ah,'$'

m_init_fail db "FAILED",0dh,0ah,'$'

m_ok db 0dh,0ah,"‚�

Комментариев нет:

Отправить комментарий