flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > what's the fastest way to read from CD? |
Author |
|
edfed 21 Jan 2008, 01:47
what about using UDMA?
if i well understand, UDMA covers the first 16 Mb of memory. and about mem to mem copy, dma is able to do that. |
|||
21 Jan 2008, 01:47 |
|
sinsi 21 Jan 2008, 05:54
Is this from your own OS, from DOS or from a dosbox in windows (or linux, or what...)?
|
|||
21 Jan 2008, 05:54 |
|
zhak 21 Jan 2008, 07:52
it's from my own boot loader. I want to make live distributive, so I use boot from cd, no-emulation mode. at first, i loaded all necessary stuff (kernel, drivers, etc.) from cd. but i decided to map system disk in the memory to make cd-rom drive fully available for user.
i've thought about using dma, but 16MB limit is actually a problem. what if more than 16MB should be loaded in future??? one more thing, i'm not familiar with dma. I've read some articles about using dma with floppy drive controller, but nothing about using it with cd-rom. for example, what channel should be used, and all the rest... i'll appreciate any help from your side |
|||
21 Jan 2008, 07:52 |
|
sinsi 21 Jan 2008, 07:58
So are you using PIO to read the CD? in real mode?
|
|||
21 Jan 2008, 07:58 |
|
zhak 21 Jan 2008, 08:53
It seems so. I use INT 13h Fn 42h.
I didn't want to access cd-rom via i/o ports to keep boot loader as compact as possible. Hmm, I though right now, that one can use SATA cd-rom instead of IDE. In that case using i/o ports becomes even more complicated... maybe using direct access to cd-rom in boot loader is not a good idea? This code is executed only once, so it's better not to make it overcomplicated. |
|||
21 Jan 2008, 08:53 |
|
Octavio 21 Jan 2008, 09:39
edfed wrote: what about using UDMA? this limit is for old dma chips (floppy,sb) a modern pci bus master controler can acces all memory. |
|||
21 Jan 2008, 09:39 |
|
zhak 21 Jan 2008, 11:57
maybe you've got some samples or links to good articles on programming udma?
|
|||
21 Jan 2008, 11:57 |
|
tom tobias 21 Jan 2008, 12:15
http://board.flatassembler.net/topic.php?t=6299
http://board.flatassembler.net/topic.php?t=1386 (see the post by anton on 30 June 2004, links seem still active!) |
|||
21 Jan 2008, 12:15 |
|
f0dder 21 Jan 2008, 12:15
Any storage device is so slow (seek as well as transfer) that you shouldn't worry about memory copying in any way. Even the fastest harddrives can't do 100MB/s yet except for bursts, and 100MB/s speed was much less than memory bandwidth even many years ago.
You do need to use DMA though, and UDMA if the drive supports it (not all optical drives do). Not because of memory speed, but because PIO access mode can bring even a quadcore system to it's knees So... even if you had 16mb low memory DMA limit, it wouldn't be a problem DMA'ing there and moving to the real target location. |
|||
21 Jan 2008, 12:15 |
|
Japheth 21 Jan 2008, 21:19
for UDMA access you can look the UDMA XCDROM32 source in jemm569s.zip at
http://www.japheth.de/Jemm.html UDMA has no 16 MB limit and it's faster than PIO. Accessing SATA devices is not that different - it is still ATA/ATAPI. |
|||
21 Jan 2008, 21:19 |
|
Mihail_b 01 May 2011, 21:25
Just in case you need this ...
It's how you can read or send any SCSI packet to a cd/dvd drive Code: #Define atapi_Read10 &h28 Type atapi_packet_READ10 Field=1 As UByte cmd, reserved1 As UInteger lba As UByte reserved2 As UShort transfer_len As UByte resrved3(1 To 3) End Type Function pioreadideatapi10(ide As UByte, typ As UByte,sector As UInteger, counts As Ushort,where As Any ptr)As UInteger If where=0 Then Exit function Dim As atapi_packet_READ10 aprd dim as ulongint ssee dim as ushort cou dim as uinteger sect dim as ushort i for i=1 to counts sect=sector+(i-1) Asm push eax mov ax,1 xchg al,ah mov [cou],ax mov eax,[sect] xchg al,ah rol eax,16 xchg al,ah mov [sect],eax pop eax end asm aprd.cmd=atapi_Read10 aprd.lba=sect aprd.transfer_len=cou function=pioreadideatapi(ide,typ,@aprd,ssee,2048,cptr(ubyte ptr,where)+((i-1) shl 11)) next i End Function Function pioreadideatapi(ide As UByte, typ As UByte,packet As Any Ptr,sector As UlongInt, counts As Uinteger,where As Any ptr)As UInteger If where=0 Then Exit function if packet=0 then exit function if ide >1 or typ>1 then exit function Dim As Uinteger c_ide Dim As Uinteger c_typ,s_reg dim as uinteger stat,did,marked Select Case ide Case 0 c_ide=&h1f0 s_reg=&h3f6 Case 1 c_ide=&h170 s_reg=&h376 End Select typ And=&h01 typ Shl= 4 'select which cannel ... Master(0) / Slave(1) Asm pushad mov edx,0 mov dx,[c_ide] add dx,7 LOOP1: IN AL, DX 'sets AL to status register (which is 8 bits) 'If the first bit of the status register (BUSY) isn't 0, the device is busy, 'so keep looping until it isn't. AND AL, &b10000000 JNE LOOP1 '---------------------------------------------------------------------------- 'Clear interrupts so something doesn't interrupt the drive or controller 'while this program is working. CLI '---------------------------------------------------------------------------- mov dx,[c_ide] add dx,7 LOOP2: IN AL, DX 'sets AL to status register again 'If the second bit of the status register (DRDY) isn't 1, the device isn't 'ready, so keep looping until it is. AND AL, &B01000000 JE LOOP2 '---------------------------------------------------------------------------- mov dx,[c_ide] add dx,6 MOV AL, &ha0 '0 selects device 0 (master). 10h would select device 1 (slave). Or al, [typ] OUT DX, AL 'selects master device 'IMPORTANT: Set nIEN before you send the PACKET command! 'Let's set nIEN to 1 so we can skip the INTRQ_Wait state. MOV DX, [s_reg] 'Device Control register MOV AL, &b00001010 'nIEN is the second bit from the right here OUT DX, AL 'nIEN is now one! mov dx,[c_ide] add dx, 1 'Point to ATAPI - Features mov al,0 out dx,al 'if bit 0 is = 0 PIO transfer else DMA transfer mov dx,[c_ide] add dx, 3 'Point to byte count registers. mov ax,[counts] 'Output data-transfer length. out dx,al inc dx mov al,ah out dx,al mov dx,[c_ide] add dx,7 MOV AL, &h0A0 'PACKET command OUT DX, AL 'sends the command! 'After sending the PACKET command, the host is to wait 400 nanoseconds before 'doing anything else. MOV ECX,&h0FFFF WAITLOOP: LOOPNZ WAITLOOP '---------------------------------------------------------------------------- mov dx,[c_ide] add dx,7 LOOP3: IN AL, DX 'sets AL to status register again 'Poll until BUSY bit is clear. AND AL, &b10000000 JNE LOOP3 'Also, poll until DRQ is one. mov dx,[c_ide] add dx,7 LOOP4: IN AL, DX AND AL, &b00001000 JE LOOP4 '---------------------------------------------------------------------------- 'NOW WE START SENDING THE COMMAND PACKET!!! MOV ECX, 6 'do this 6 times because it's 6 word writes (a word is 2 bytes) MOV ESI, [packet] 'DS:SI now points to the buffer which contains our ATAPI command packet CLD 'clear direction flag so SI gets incremented, not decremented COMPACKLOOP: 'command packet sending loop mov dx,[c_ide] 'Because we're going to need to write a word (2 bytes), we can't just use an '8-bit register like AL. For this operation, we'll need to use the full width 'of the 16-bit accumulator AX. We'll use the LODSW opcode, which loads AX 'with whatever DS:SI points to. Not only this, but if the direction flag is 'cleared (which we did a few lines above with the CLD instruction), LODSW 'also auto-increments SI. LODSW OUT DX, AX 'send the current word of the command packet!!! MOV DX, [s_reg] 'Alternate Status Register IN AL, DX 'wait one I/O cycle LOOPNZ COMPACKLOOP '---------------------------------------------------------------------------- 'Once again, let's read the Alternate Status Register and ignore the result, 'since the spec says so. MOV DX, [s_reg] IN AL, DX 'pushad 'end asm 'print "complete sending PACKET ! "; 'asm 'popad 'Okay... That's done. 'Time to poll the status register until BUSY is 0 again. mov dx,[c_ide] add dx,7 LOOP5: IN AL, DX And AL, &b10000000 JNE LOOP5 'BUSY is zero here. mov dx,[c_ide] add dx,7 'LOOP23: IN AL, DX And AL, &B00001000 'JE LOOP23 'We're also supposed to check DRQ JE cont1_02 'if drq=0 no DATA (because command is done )! continue_to_get: MOV DX, [s_reg] in AL,dx 'delay for a while mov dx,[c_ide] 'Get controller-buffer byte count. add dx,5 in al,dx mov ah,al dec dx in al,dx mov [marked],ax mov dx,[c_ide] mov ecx,[counts] cmp ax,cx je eq1111 movzx ecx,ax mov [stat],ecx sub [counts],ecx 'pushad 'end asm 'print "[well stat=";stat;" while counts=";counts;" did=";did;"]" 'asm 'popad eq1111: shr ecx,1 mov edi,[where] add edi,[did] cld rep insw movzx ecx,word ptr [marked] add [did],ecx 'pushad 'end asm 'print "Veve !" 'asm 'popad MOV DX, [s_reg] 'Device Control register in al,dx mov dx,[c_ide] add dx,7 'in al,dx 'in al,dx mov ecx,100 LOOP51: dec ecx jcxz cont1_01 IN AL, DX And AL, &b10000000 JNE LOOP51 cont1_01: mov dx,[c_ide] add dx,7 IN AL, DX And AL, &B01000 'bt ax,3:jnc short continue_to_get jne short continue_to_get cont1_02: MOV DX, [s_reg] 'Device Control register 'in al,dx MOV AL, &b00001000 'nIEN is the second bit from the right here OUT DX, AL 'nIEN is now on! STI popad End Asm 'movsb1(the_where,where,counts) Function=1 End Function |
|||
01 May 2011, 21:25 |
|
tom tobias 06 May 2011, 09:13
Thank you, well written.
|
|||
06 May 2011, 09:13 |
|
neville 07 May 2011, 10:25
I was reading the posts in this thread and thinking somebody's gotta tell zhak that mem-to-mem copies are definitely not slow compared to rotating storage media - even buffered 64K at a time.
Then I saw this post: f0dder wrote: Any storage device is so slow (seek as well as transfer) that you shouldn't worry about memory copying in any way. Even the fastest harddrives can't do 100MB/s yet except for bursts, and 100MB/s speed was much less than memory bandwidth even many years ago. _________________ FAMOS - the first memory operating system |
|||
07 May 2011, 10:25 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.