|
ATA & ATAPI [ DISK & CD-ROM DRIVE ] ASSEMBLY PROGRAMMING DIRECT I/O [ TR-DOS project -
CENTRAL.COM - P2002.COM i/o drafts ] |
||||
| ataid.html | ataid.zip | atapinq.html | atapinq.zip | iso9660.zip |
; *****************************************************************************
;
; READPVDL.ASM [ ATAPI I/O code draft - READ PRIMARY VOLUME DESCRIPTOR ]
; Reads&Shows ISO9660 Primary Volume Descriptor
; at Starting Sector + 16 of the 1st Track in the Last Session of CD-ROM
; Copyright (C) 2002 Erdogan TAN [ 28/11/2002 ]
;
; *****************************************************************************
; ATA/IDE Command Register Block [ AT Task File ]
IdeCmdReg_R_Data equ 0 ; Data Register
IdeCmdReg_W_Data equ 0 ; Data Register
IdeCmdReg_R_Error equ 1 ; Error Register
IdeCmdReg_W_Feature equ 1 ; Feature Register
IdeCmdReg_R_SectCount equ 2 ; Sector Count Register
IdeCmdReg_W_SectCount equ 2 ; Sector Count Register
IdeCmdReg_R_Sector equ 3 ; Sector Number or LBA Bits 0-7
IdeCmdReg_W_Sector equ 3 ; Sector Number or LBA Bits 0-7
IdeCmdReg_R_Cylinder0 equ 4 ; Cylinder Bits 0-7 or LBA Bits 8-15
IdeCmdReg_W_Cylinder0 equ 4 ; Cylinder Bits 0-7 or LBA Bits 8-15
IdeCmdReg_R_Cylinder1 equ 5 ; Cylinder Bits 8-15 or LBA Bits 16-23
IdeCmdReg_W_Cylinder1 equ 5 ; Cylinder Bits 8-15 or LBA Bits 16-23
IdeCmdReg_R_DriveHead equ 6 ; Drive & Head Bits or LBA Bits 24-27
IdeCmdReg_W_DriveHead equ 6 ; Drive & Head Bits or LBA Bits 24-27
IdeCmdReg_R_Status equ 7 ; Status Register
IdeCmdReg_W_Command equ 7 ; Command Register
; IDE Status Register Bits
IdeCmdReg_R_Status_BSY equ 80h ; Bit 7
IdeCmdReg_R_Status_DRDY equ 40h ; Bit 6
IdeCmdReg_R_Status_DWF equ 20h ; Bit 5
IdeCmdReg_R_Status_DSC equ 10h ; Bit 4
IdeCmdReg_R_Status_DRQ equ 08h ; Bit 3
IdeCmdReg_R_Status_CORR equ 04h ; Bit 2
IdeCmdReg_R_Status_IDX equ 02h ; Bit 1
IdeCmdReg_R_Status_ERR equ 01h ; Bit 0
; [ ATA Commands ]
; ATA PACKET INTERFACE Command
ATAPI_PKT_COMMAND equ 0A0h ; Mandatory
; ATAPI_IDENTIFY_DRIVE equ 0A1h ; Mandatory
; ATAPI_SOFT_RESET equ 08h ; Mandatory
; ATAPI_SERVICE equ A2h ; Optional
; [ ATAPI Pkt Commands - as a parameter of ATA Command A0h ]
ATAPI_READ_TOC equ 43h ; Operation Code
ATAPI_READ equ 28h ; Operation Code
Present segment Para 'code'
assume CS:Present, DS:Present, ES:Present, SS:Present
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_start
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_start proc far
org 100h
start:
push ds
pop es
mov byte ptr [Command], ATAPI_PKT_COMMAND
call proc_clear_screen
mov si, offset READ_Table_Header
call proc_printmsg
mov word ptr [Port], 1F0h
mov byte ptr [Drive], 0
mov word ptr [READ_T_Port], "F1" ; 1F0h
mov byte ptr [READ_T_Drive], "0"
call proc_atapi_read
jc short pass_1F0_0
call proc_show_pvd_table
pass_1F0_0:
mov byte ptr [Drive], 10h ; Drive 1
mov byte ptr [READ_T_Drive], "1"
call proc_atapi_read
jc short pass_1F0_1
call proc_show_pvd_table
pass_1F0_1:
mov word ptr [Port], 170h
mov byte ptr [Drive], 0
mov word ptr [READ_T_Port], "71" ; 170h
mov byte ptr [READ_T_Drive], "0"
call proc_atapi_read
jc short pass_170_0
call proc_show_pvd_table
pass_170_0:
mov byte ptr [Drive], 10h ; Drive 1
mov byte ptr [READ_T_Drive], "1"
call proc_atapi_read
jc short loc_terminate
call proc_show_pvd_table
loc_terminate:
int 20h
proc_start endp
proc_atapi_read proc near
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
mov cx, 0FFFFh
loc_read_status_reg_1:
in al, dx
and al, ideCmdReg_R_Status_BSY
jz short loc_write_ide_command_1
loop loc_read_status_reg_1
jmp short loc_device_is_busy
loc_write_ide_command_1:
mov dx, ideCmdReg_W_DriveHead
add dx, word ptr [Port]
mov al, byte ptr [Drive]
or al, 0EFh ; Select Drive via Bit 4
out dx, al
mov cx, 0FFFFh
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
loc_read_status_reg_2:
in al, dx
and al, 80h ; BSY
jz short loc_write_ide_command_2
loop loc_read_status_reg_2
jmp short loc_device_is_busy
loc_write_ide_command_2:
mov dx, ideCmdReg_W_Command
add dx, word ptr [Port]
mov al, byte ptr [Command]
out dx, al
mov cx, 0FFFFh
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
loc_read_status_reg_3:
in al, dx
test al, 80h ; BSY bit
jnz short pass_drq_err_check_1
test al, 01h ; ERR bit
jnz short loc_ata_ide_io_error
test al, 08h ; DRQ bit
jnz short loc_write_command_packet_1
pass_drq_err_check_1:
loop loc_read_status_reg_3
jmp short loc_device_is_busy
loc_write_command_packet_1:
mov dx, ideCmdReg_R_Data
add dx, word ptr [Port]
mov si, offset TOC_Command_Packet_Buffer
mov cx, 6
loc_write_command_packet_1a:
lodsw
out dx, ax
loop loc_write_command_packet_1a
mov cx, 0FFFFh
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
loc_read_status_reg_4:
in al, dx
test al, 80h ; BSY bit
jnz short pass_drq_err_check_2
test al, 01h ; ERR bit
jnz short loc_ata_ide_io_error
test al, 08h ; DRQ bit
jnz short loc_read_data_reg_1a
pass_drq_err_check_2:
loop loc_read_status_reg_4
loc_device_is_busy:
; mov si, Offset Device_is_busy
; call proc_printmsg
stc
retn
loc_ata_ide_io_error:
; mov si, offset IO_Error
; call proc_printmsg
stc
retn
loc_read_data_reg_1a:
mov dx, ideCmdReg_R_Data
add dx, word ptr [Port]
mov di, offset TOC_Data_Buffer
loc_Read_Data_reg_1b:
in ax, dx
xchg ah,al
mov cx, ax
shr cx,1
stosw
loc_Read_Data_reg_1c:
in ax, dx
stosw
loop loc_Read_Data_reg_1c
mov cx, 0FFFFh
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
loc_read_status_reg_8:
in al, dx
and al, 80h ; BSY
jz short loc_write_ide_command_3
loop loc_read_status_reg_8
loc_write_ide_command_3:
mov dx, ideCmdReg_W_DriveHead
add dx, word ptr [Port]
mov al, byte ptr [Drive]
or al, 0EFh ; Select Drive via Bit 4
out dx, al
mov cx, 0FFFFh
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
loc_read_status_reg_5:
in al, dx
and al, 80h ; BSY
jz short loc_write_ide_command_4
loop loc_read_status_reg_5
jmp short loc_device_is_busy
loc_write_ide_command_4:
mov al, byte ptr Last_Session_Number
call proc_hex
mov word ptr [READ_T_Session], ax
mov si, offset First_Track_Absolute_Address
mov di, offset PVD_LBA
lodsw
xchg ah,al
push ax
lodsw
xchg ah,al
pop dx
add ax, 10h
adc dx, 0
xchg dh,dl
xchg ah,al
push ax
push dx
pop ax
stosw
pop ax
stosw
loc_write_ide_command_4a:
mov dx, ideCmdReg_W_Command
add dx, word ptr [Port]
mov al, byte ptr [Command]
out dx, al
mov cx, 0FFFFh
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
loc_read_status_reg_6:
in al, dx
test al, 80h ; BSY bit
jnz short pass_drq_err_check_3
test al, 01h ; ERR bit
jnz loc_ata_ide_io_error
test al, 08h ; DRQ bit
jnz short loc_write_command_packet_2
pass_drq_err_check_3:
loop loc_read_status_reg_6
jmp loc_device_is_busy
loc_write_command_packet_2:
mov dx, ideCmdReg_R_Data
add dx, word ptr [Port]
mov si, offset PVD_Command_Packet_Buffer
mov cx, 6
loc_write_command_packet_2a:
lodsw
out dx, ax
loop loc_write_command_packet_2a
mov cx, 0FFFFh
mov dx, ideCmdReg_R_Status
add dx, word ptr [Port]
loc_read_status_reg_7:
in al, dx
test al, 80h ; BSY bit
jnz short pass_drq_err_check_4
test al, 01h ; ERR bit
jnz loc_ata_ide_io_error
test al, 08h ; DRQ bit
jnz short loc_read_data_reg_2a
pass_drq_err_check_4:
loop loc_read_status_reg_7
jmp loc_device_is_busy
loc_read_data_reg_2a:
mov dx, ideCmdReg_R_Data
add dx, word ptr [Port]
mov cx, 1024
mov di, offset PVD_Buffer
push di
loc_Read_Data_reg_2b:
in ax, dx
stosw
loop loc_Read_Data_reg_2b
pop si
mov di, offset READ_T_PVD_b0
lodsb
call proc_hex ; AL= Input, AX= Output as HEX num characters.
stosw
mov di, offset READ_T_PVD_ISO9660_ID
mov cx, 5
rep movsb
mov di, offset READ_T_PVD_b6
lodsb
call proc_hex
stosw
mov di, offset READ_T_PVD_b7
lodsb
call proc_hex
stosw
mov di, offset READ_T_PVD_SYSID
mov cx, 16
rep movsw
mov di, offset READ_T_PVD_VOLID
mov cx, 16
rep movsw
mov si, offset PVD_Buffer_TOTALSECS
mov di, offset READ_T_PVD_TOTALSECS
; 32 bit Number as First Little Endian (al,ah,dl,dh)
lodsw
push ax ; Byte 0 will be Byte 3 after "pop ax"
lodsw
call proc_hex_double
xchg dx, ax
push dx
stosw
pop ax
stosw
pop ax
call proc_hex_double
xchg ax,dx
push dx
stosw
pop ax
stosw
mov si, offset PVD_Buffer_SECSIZE
mov di, offset READ_T_PVD_SECSIZE
; 16 bit Number as First Little Endian (al,ah)
lodsw
call proc_hex_double
xchg dx,ax
push dx
stosw
pop ax
stosw
clc
retn
proc_atapi_read endp
proc_show_pvd_table proc near
mov si, offset READ_Data_Table
loc_print_PVD_Table:
mov cx, offset end_of_table
sub cx, si
loc_print_table_cx:
lodsb ; Load byte at DS:SI to AL
mov AH,0Eh
mov BX,07h
int 10h ; BIOS Service func ( ah ) = 0Eh
; Write char as TTY
;AL-char BH-page BL-color
loop short loc_print_table_cx
; Above instructions are used for preventing STOP due to al=0.
; Otherwise, 'call proc_printmsg' would be used.
mov si, offset Msg_PressAnyKey
call proc_printmsg
xor ah, ah
int 16h
retn
proc_show_pvd_table endp
proc_clear_screen proc near
mov ah, 0Fh
int 10h
mov ah, 0
int 10h
retn
proc_clear_screen endp
proc_printmsg proc near
loc_print:
lodsb ; Load byte at DS:SI to AL
and AL,AL
je short loc_return ; If AL = 00h then return
mov AH,0Eh
mov BX,07h
int 10h ; BIOS Service func ( ah ) = 0Eh
; Write char as TTY
;AL-char BH-page BL-color
jmp short loc_print
loc_return:
retn
proc_printmsg endp
;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; From binary (byte) to hexadecimal (character) converter ;
; ;
; input -> AL = byte (binary number) to be converted ;
; output -> AH = First character of hexadecimal number ;
; output -> AL = Second character of hexadecimal number ;
; ;
; (c) Erdogan TAN 1998 - 1999 ;
;............................................................;
; 1998
proc_hex proc near
db 0D4h,10h ; Undocumented inst. AAM
; AH = AL / 10h
; AL = AL MOD 10h
or AX,'00' ; Make it ZERO (ASCII) based
xchg AH,AL
; 1999
cmp AL,'9'
jna short pass_ccl_al
add AL,7
pass_ccl_al:
cmp AH,'9'
jna short pass_ccl_ah
add AH,7
pass_ccl_ah:
; 1998
retn
proc_hex endp
;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; From binary (word) to hexadecimal (character) converter ;
; ;
; input -> AX = word (binary number) to be converted ;
; output -> DX = First 2 characters of hexadecimal number ;
; output -> AX = Last 2 characters of hexadecimal number ;
; ;
; (c) Erdogan Tan [ 28/1/2002 ] ;
;............................................................;
proc_hex_double proc near
push cx
xor dx, dx
mov cx, 10h
div cx ; Q in AX, R in DX (DL)
xchg dh, dl ; DH= 0, R in DL <- CX= 10h
push dx ; R in DH, DL= 0
xor dh, dh
div cx
push dx ; R in DL, DH= 0, AX <= FFh
div cl ; AX <= 0Fh
; R in AH, Q in AL, AL (Q) is 0
push ax
pop dx ; High Word Characters is in DX
pop cx ; R in CL
pop ax ; R in AH, AL = 0
or al, cl
or DX,'00'
cmp DL,'9'
jna short pass_cc_dl
add DL,7
pass_cc_dl:
cmp DH,'9'
jna short pass_cc_dh
add DH,7
pass_cc_dh:
or AX, '00'
cmp AL,'9'
jna short pass_cc_al
add AL,7
pass_cc_al:
cmp AH,'9'
jna short pass_cc_ah
add AH,7
pass_cc_ah:
pop cx
retn
proc_hex_double endp
Command: db 0
Port: dw 0
Drive: db 0
; ATAPI READ (10) Command Parameters (Input - Command packet)
PVD_Command_Packet_Buffer:
db 28h ; Operation Code
db 0 ; Byte 1- Reserved
PVD_LBA:
dd 10000000h ; Logical Block Address (16= ISO9660 Primary Volume Descriptor)
db 0 ; Byte 6 - Reserved
dw 0100h ; Transfer Lengt (1 sector)
db 3 dup(0) ; Byte 9 to 11 are Reserved
; ATAPI READ TOC Command Parameters (Input - Command packet)
TOC_Command_Packet_Buffer:
db 43h ; Operation Code
MSF_Bit:
db 0 ; Byte 1 - Bit 1 = MSF bit. Other bits are reserved. 0= LBA, 1= MSF
Format_Bits:
db 00h ; Byte 2 - Bit 0,1,2 are Format bits.
;O1b= Multi-Session mode, returns the 1st session number, last session number
;and last session's starting track address (LBA or MSF)
; Other bits are reserved
db 3 dup(0) ; Reserved bytes
Starting_Track: ; or Starting_Session
db 0 ; Byte 6 - Starting Track / Session Number - Reserved in Format 01b
Allocation_Lenght:
dw 0C00h ; Allocation Lengt (12 bytes)
db 40h ; Byte 9 - Bit 6,7 are Format bits when Format in Byte 2 is zero.
; Other bits of Byte 9 are reserved.
; Format 00b= Backward Compatible Mode (No Multisession)
; Format 01b= Multi Session Mode
; Format 10b= Returns all Sub-Channel Q data in the lead in (TOC) area.
dw 0 ; Byte 10,11 are reserved.
Msg_PressAnyKey:
db "Press any key to continue ..."
db 0Dh, 0Ah, 0
READ_Table_Header:
db 7
db 0Dh, 0Ah
db "ISO9660 Primary Volume Descriptor [ (c) Erdogan Tan 2002 ]"
db 0Dh, 0Ah, 0
READ_Data_Table:
db 0Dh, 0Ah
db "I/O Port : "
READ_T_Port: db "1F0h"
db 0Dh, 0Ah
db "Drive : "
READ_T_Drive: db "0"
db 0Dh, 0Ah
db 0Dh, 0Ah
db "Session : "
READ_T_Session:
db "00h"
db 0Dh, 0Ah
db 0Dh, 0Ah
db "Byte 0 : "
READ_T_PVD_b0:
db "00h"
db 0Dh, 0Ah
db "ISO9660 Identifier : "
READ_T_PVD_ISO9660_ID:
db 6 dup(20h)
db 0Dh,0Ah
db "Byte 6 : "
READ_T_PVD_b6:
db "00h"
db 0Dh, 0Ah
db "Byte 7 : "
READ_T_PVD_b7:
db "00h"
db 0Dh,0Ah
db "System Identifier : "
READ_T_PVD_SYSID:
db 32 dup(20h)
db 0Dh,0Ah
db "Volume Identifier : "
READ_T_PVD_VOLID:
db 32 dup(20h)
db 0Dh,0Ah
db "Total Number of Sectors : "
READ_T_PVD_TOTALSECS:
db 8 dup("0")
db "h"
db 0dh, 0Ah
db "Sector Size : "
READ_T_PVD_SECSIZE:
db 4 dup("0")
dd "h"
db 0Dh, 0Ah
db 0Dh, 0Ah
end_of_table:
db 0Dh, 0Ah,0
; Drive_Is_Not_Ready:
; db "Drive is not ready !"
; db 0Dh, 0Ah, 0
; Device_Is_Busy:
; db "Device is busy !"
; db 0Dh, 0Ah, 0
; IO_Error:
; db "IO Error !"
; db 0Dh, 0Ah,0
; READ TOC Data Buffer
TOC_Data_Buffer:
TOC_DATA_Lenght:
dw 0
First_Session_Number:
db 0
Last_Session_Number:
db 0
; TOC Track Descriptors
db 0 ; Reserved
ADR_Control:
db 0 ; Bit 0,1,2,3 are Control bits, Bits 4,5,6,7 are ADR bits
First_Track_LS:
db 0 ; First Track Number in Last Session
db 0 ; Reserved
First_Track_Absolute_Address: ; in Last Session
dd 0 ; 4 bytes - LBA or MSF format ( LBA returns when MSF bit is 0 )
db 792 dup(0) ; 100 sessions * 8 bytes structure + 4 bytes = 804 bytes max.
; ISO9660 Primary Volume Descriptor Buffer
PVD_Buffer:
PVD_Buffer_b0:
db 0
PVD_Buffer_ISO9660_ID:
db 5 dup(20h)
PVD_Buffer_b6:
db 0
PVD_Buffer_b7:
db 0
PVD_Buffer_SYSID:
db 32 dup (20h)
PVD_Buffer_VOLID:
db 32 dup (20h)
db 8 dup(0)
PVD_Buffer_TOTALSECS: ; First Little Endian = al,ah,dl,dh
db 4 dup(0)
; PVD_Buffer_TOTALSECS: [ First Big Endian = dh,dl,ah,al ]
db 4 dup (0)
db 32 dup (0)
dd 0
dd 0
PVD_Buffer_SECSIZE: ; First Little Endian
dw 0
; PVD_Buffer_SECSIZE: [ First Big Endian ]
dw 0
PVD_Buffer_PTAB_L:
db 8 dup(0)
PVD_Buffer_Num_Of_1st_Sector:
dd 0
dd 0
dd 0
dd 0
PVD_Buffer_Root_Dir_Record:
db 34 dup(0)
PVD_Buffer_VolSet_ID:
db 128 dup (20h)
PVD_Buffer_Publisher_ID:
db 128 dup (20h)
PVD_Buffer_Data_Prep_ID:
db 128 dup (20h)
PVD_Buffer_Appl_ID:
db 128 dup (20h)
PVD_Buffer_CopyRight_File_ID:
db 37 dup (20h)
PVD_Buffer_Abstract_File_ID:
db 37 dup (20h)
PVD_Buffer_Biblio_File_ID:
db 37 dup (20h)
PVD_Buffer_Creation_DateTime:
db 17 dup (20h)
PVD_Buffer_LastModif_DateTime:
db 17 dup (20h)
PVD_Buffer_Expire_DateTime:
db 17 dup (20h)
PVD_Buffer_Effective_DateTime:
db 17 dup (20h)
db 1
db 0
db 512 dup (0)
db 653 dup (0)
Present ends
end start
|
||||
| index.html | specs.html | trdos.html | ||