AboutAdvertisingAwardsContact usNewsMessageboards Back to messagelist Re: Disk access... Posted by ports on February 22, 2000 at 12:10:14 PM TITLE Freehafer's use ports to read floppy disk A: sectors program ; ; Bibliography ; ; 1. Help with DMA programming is found in The Indespensable PC Hardware ; Book, Messmer, Addison-Wesley Longman Limited, ©1997, page 721. ; ; 2. Help with port programming is found in The Undocumented PC, ; Gilluwe, Addison-Wesley Developers Press, ©1997, pages 525, 1057. ; ;........................................................................ msg MACRO msgout ; mov AH, 09h ; function 09h lea DX, msgout ; DX holds message int 21h ; display string interupt ENDM ; ;........................................................................ .MODEL small ; directive placing all memory in one segment ;........................................................................ .stack 2000h ; .data ; Message DB 0Ah,0Dh," This program uses ports to read a sector of A:",0Ah,0Dh,'$' CW DB 10,13,10,13," (C)1999 Inniea Publishing Company! R",153,142,"K NOG!",0Ah,0Dh," Freehafer's Read Sector With Ports Program Is Terminated! ",0Ah,0Dh,0Ah,0Dh,'$' msgENT DB 10,13,10,13," Enter a 'y' or 'Y' if you want to display",10,13," sector contents on screen: ",'$' CRLF DB 10,13,'$' msgLine DB 10,13," **************SECTOR CONTENTS***************",10,13,'$' msgSECTOR DB 10,13," Enter sector number 1 to 18: ",'$' msgTRACK DB 10,13," Enter track number 0 to 79: ",'$' msgSIDE DB 10,13," Enter side number 0 to 1: ",'$' NUM DW 0 counter DW 0 buffer DB 512 dup('t') buffy DB 512 dup(?) on_off_switch EQU 1Ch ; motor_on compare_s DB 0 ; send_controller compare_r DB 0 ; receive_controller compare_x DB 0 ; recalibrate_a compare_t DB 0 ; seek_track_side command_byte DB ? ; result_byte DB ? ; side DB 0 ; track DB 0 ; sector DB 0 ; INPNUM DW 0 ; dma_access_opperation_code DB ? dma_low_order_count_byte DB ? dma_high_order_count_byte DB ? ;........................................................................ .code ; ;........................................................................ start: ; begin algorithm ;........................................................................ ; ; move data segment into DS ;........................................................................ mov AX, @data ; base address mov DS, AX ; of data segment ;........................................................................ ; ; get inputs ;........................................................................ msg Message ; describe what program does ;........................................................................ msg msgSECTOR ; sector CALL InputInt ; mov AL, byte ptr NUM ; mov sector, AL ; msg msgTRACK ; track CALL InputInt ; mov AL, byte ptr NUM ; mov track, AL ; msg msgSIDE ; side CALL InputInt ; mov AL, byte ptr NUM ; mov side, AL ; ;........................................................................ ; ; read media id of A: ;........................................................................ mov AL, 00h ; drive A: LEA BX, buffy ; ES:BX mov CX, 01h ; number of sectors to read mov DX, 00h ; boot sector int 25h ; absolute read interrupt ;........................................................................ ; ; delay ;........................................................................ mov AX, 0 ; mov counter, AX ; first_loop: ; beep delay mov AH, 02h ; mov DL, 07h ; int 21h ; .IF(counter < 15) ; ;........................................................................ mov AH, 86h ; system wait function mov CX, 02h ; CX = 1E DX = 8480h for 2 seconds mov DX, 00h ; 131.072 milliseconds int 15h ; added dealy ;........................................................................ inc counter ; jmp first_loop ; .ENDIF ; ;........................................................................ ; ; ES:BX ;........................................................................ mov BX, seg buffer ; mov ES, BX ; mov BX, offset buffer ; ;........................................................................ ;***********************************; DIRECT MEMORY ACCESS mov AL, 56h ; mov dma_access_opperation_code, AL mov AL, 0FFh ; mov dma_low_order_count_byte, AL mov AL, 1h ; mov dma_high_order_count_byte, AL call dma_access ; ;........................................................................ CALL motor_on ; CALL recalibrate_a ; retract head to track 0 CALL seek_track_side ; seek desired track and side CALL read_sector_id ; verify side ;........................................................................ ;***********************************; WRITE TO CONTROLLER ;........................................................................ ; ; Send Byte 0 Command To Port ;........................................................................ mov AL, 46h ; 70d = 46h = 0100 0110b read sector command mov command_byte, AL ; CALL send_controller ; send command to port ;........................................................................ ; ; Send Byte 1 ;........................................................................ mov CL, 4 ; mov AL, side ; alternate between 0x00 and 0x04 mul CL ; 0000 0(head = 0 or 1)(drive a: = 0 0) mov command_byte, AL ; CALL send_controller ; send command to port ;........................................................................ ; ; Send Byte 2 ;........................................................................ mov AL, track ; mov command_byte, AL ; cylinder CALL send_controller ; ;........................................................................ ; ; Send Byte 3 ;........................................................................ mov AL, side ; head mov command_byte, AL ; CALL send_controller ; send command to port ;........................................................................ ; ; Send Byte 4 ;........................................................................ mov AL, sector ; sector # up to 37 max mov command_byte, AL ; CALL send_controller ; ;........................................................................ ; ; Send Byte 5 ;........................................................................ mov AL, 2 ; Byte 5 = 2 for 512 bytes per sector mov command_byte, AL ; CALL send_controller ; ;........................................................................ ; ; Send Byte 6 ;........................................................................ mov AL, 12h ; 18d = last sector on track mov command_byte, AL ; CALL send_controller ; ;........................................................................ ; ; Send Byte 7 ;........................................................................ mov AL, 1Bh ; 3 1/2" write or read = 1Bh = 27d = 0001 1011b mov command_byte, AL ; gap CALL send_controller ; ;........................................................................ ; ; Send Byte 8 ;........................................................................ mov AL, 0h ; 0 or 0FFh = 255d unused = 01111111b mov command_byte, AL ; CALL send_controller ; ;........................................................................ ;***********************************; READ FROM CONTROLLER ;........................................................................ CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; ;........................................................................ CALL motor_off ;........................................................................ ;***********************************; DISPLAY SECTOR CONTENTS ;........................................................................ ; ; display sector contents ;........................................................................ msg msgENT ; do you want boot sector contents displayed mov AH, 01h ; read character function int 21h ; call interrupt .IF(AL != 89 && AL != 121) ; if 'Y' of 'y' not entered skip display jmp skipper ; .ENDIF ; msg CRLF ; ;........................................................................ msg msgLine ; display line of stars disloop: ; beginning of loop mov BX, counter ; counter mov AL, buffer[BX] ; buffer array int 29h ; display character in AL inc counter ; increment counter .IF(counter jmp disloop ; end of loop .ENDIF ; end of counter test msg CRLF ; new line msg msgLine ; display line of stars skipper: ;........................................................................ msg CW ; display copyright ;........................................................................ ; ; end ;........................................................................ mov AX,4C00h ; termination function int 21h ; termination interupt ;........................................................................ ; PROCEDURES************************************************************* ;........................................................................ ; PROCEDURE TO INPUT NUMBER********************************************** ;........................................................................ InputInt proc ; push CX ; push BX ; mov BX, 0 ; mov CX, 0 ; mov NUM, 0 ; READ: ; mov AH, 1 ; int 21h ; mov DL, AL ; cmp AL, '0' ; jl ExitProc ; cmp AL, '9' ; jg ExitProc ; Number: ; mov AH, 0 ; sub AL, '0' ; mov CX, AX ; mov AX, 10 ; mul BX ; add AX, CX ; mov BX, AX ; jmp Read ; ExitProc: ; mov AX, BX ; pop BX ; pop CX ; mov NUM, AX ; ret ; InputInt endp ; ;........................................................................ ; PROCEDURE TO DELAY***************************************************** ;........................................................................ delay_1 proc ; mov AH, 86h ; system wait function mov CX, 00h ; CX = 1E DX = 8480h for 2 seconds mov DX, 5000h ; 5000h = 20480d = int 15h ; 20.480 milliseconds ret ; delay_1 endp ; ;........................................................................ ; PROCEDURE TO TURN ON FLOPPY DIRVE MOTOR******************************** ;........................................................................ motor_on proc ; mov DX, 3F2h ; mov AL, on_off_switch ; OUT DX, AL ; ret ; motor_on endp ; ;........................................................................ ; PROCEDURE TO TURN OFF FLOPPY DIRVE MOTOR******************************* ;........................................................................ motor_off proc ; mov DX, 3F2h ; mov AL, 0h ; OUT DX, AL ; ret ; motor_off endp ; ;........................................................................ ; PROCEDURE TO SEND CONTROLLER COMMAND BYTE****************************** ;........................................................................ send_controller proc ; send_check_again: ; CALL delay_1 ; mov DX, 3F4h ; IN AL, DX ; mov compare_s, AL ; AND compare_s, 80h ; .IF (compare_s != 80h) ; 128d = 80h = 1000 0000b jmp send_check_again ; ***** .ENDIF ; CALL delay_1 ; mov DX, 3F5h ; mov AL, command_byte ; OUT DX, AL ; ret ; send_controller endp ; ;........................................................................ ; PROCEDURE TO RECEIVE BYTES FROM CONTROLLER***************************** ;........................................................................ receive_controller proc ; receive_check_again: ; CALL delay_1 ; mov DX, 3F4h ; IN AL, DX ; mov compare_r, AL ; AND compare_r, 80h ; .IF (compare_r != 80h) ; 128d = 80h = 1000 0000b jmp receive_check_again ; ***** .ENDIF ; CALL delay_1 ; mov DX, 3F5h ; IN AL, DX ; mov result_byte, AL ; ret ; receive_controller endp ; ;........................................................................ ; PROCEDURE TO RECALIBRATE OR RETRACT TRACK TO 0************************* ;........................................................................ recalibrate_a proc ; recalibrate_it_again: ; mov AL, 7 ; recalibrate command byte mov command_byte, AL ; CALL send_controller ; mov AL, 0h ; DRIVE A: mov command_byte, AL ; CALL send_controller ; ; ; sense interrupt mov AL, 08h ; sense command byte = 08h mov command_byte, AL ; CALL send_controller ; CALL receive_controller ; result_byte 1 = status mov AL, result_byte ; mov compare_x, AL ; AND compare_x, 80h ; .IF (compare_x == 80h) ; 128d = 80h = 1000 0000b jmp recalibrate_it_again ; ***** .ENDIF ; CALL receive_controller ; result_byte 2 = track .IF(result_byte != 0) ; jmp recalibrate_it_again ; ***** .ENDIF ; ret ; recalibrate_a endp ; ;........................................................................ ; PROCEDURE TO SEEK TRACK AND SIDE*************************************** ;........................................................................ seek_track_side proc ; go_and_seek_it_again: ; mov AL, 0Fh ; seek command byte = 0Fh mov command_byte, AL ; CALL send_controller ; mov CL, 4 ; mov AL, side ; INPUT = alternate between 0x00 and 0x04 mul CL ; 0000 0(head = 0 or 1)(drive a: = 0 0) mov command_byte, AL ; CALL send_controller ; send command to port mov AL, track ; INPUT = track mov command_byte, AL ; CALL send_controller ; ;...................................; sense interrupt mov AL, 08h ; sense command byte = 08h mov command_byte, AL ; CALL send_controller ; CALL receive_controller ; mov AL, result_byte ; result_byte 1 = status mov compare_t, AL ; AND compare_t, 80h ; .IF (compare_t == 80h) ; 128d = 80h = 1000 0000b jmp go_and_seek_it_again ; ***** .ENDIF ; CALL receive_controller ; result_byte 2 = track mov AL, track ; .IF (result_byte != AL) ; jmp go_and_seek_it_again ; ***** .ENDIF ;.... ret ; seek_track_side endp ; ;....................................................................... ; PROCEDURE TO READ SECTOR ID******************************************* ;....................................................................... read_sector_id proc ; mov AL, 4Ah ; command byte mov command_byte, AL ; CALL send_controller ; mov CL, 4 ; mov AL, side ; INPUT = alternate between 0x00 and 0x04 mul CL ; 0000 0(head = 0 or 1)(drive a: = 0 0) mov command_byte, AL ; CALL send_controller ; send command to port CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; CALL receive_controller ; result_byte = side mov AL, side ; .IF (result_byte != AL) ; CALL receive_controller ; CALL receive_controller ; jmp go_and_seek_it_again ; ***** .ENDIF ;.... CALL receive_controller ; CALL receive_controller ; ret ; read_sector_id endp ; ;........................................................................ ; DIRECT MEMORY ACCESS PROCEDURE***************************************** ;........................................................................ dma_access proc ; ;........................................................................ cli ; disable interrupts ;........................................................................ ; ; disable dma1 ;........................................................................ MOV AL, 14h ; OUT 08h, AL ; DMA-1 Command Register port 8h ; command 20d = 14h = 0001 0100b ; rotating priority ; disable disabled ; memory to memory transfer ;........................................................................ ; ; mode ;........................................................................ MOV AL, dma_access_opperation_code OUT 0Bh, AL ; DMA-1 Mode Register port 0Bh ; single mode; auto; write; channel 2 ;..................................................................... ; ; split address ;..................................................................... MOV AX, ES ; MOV CL, 04h ; SHL AX, CL ; ADD AX, BX ; JC carry ; ;..................................................................... ; ; no carry ;..................................................................... MOV BX, ES ; MOV CL, 04h ; SHR BH, CL ; JMP buffer_address ; carry: ; MOV BX, ES ; MOV CL, 04h ; SHR BH, CL ; ADC BH, 0h ; buffer_address: ; OUT 0Ch, AL ; DMA-1 Clear Byte Flip-Flop ; reset flip-flop OUT 04h, AL ; DMA-1 Channel 2 Output ; Low Order Address Byte MOV AL, AH ; OUT 04h, AL ; DMA-1 Channel 2 Output ; High Order Address Byte MOV AL, BH ; page address OUT 81h, AL ; page value = 11d = 0Bh = 0000 1011 ; address bits A16 to A19 ; for DMA transfers ;........................................................................ ; ; count value ;........................................................................ OUT 0Ch, AL ; DMA-1 Clear Byte Flip-Flop ; reset flip-flop ;........................................................................ ; ; BUFFER SIZE = 84 BYTES ;........................................................................ MOV AL, dma_low_order_count_byte OUT 05h, AL ; DMA-1 Count Port ; load low order count byte MOV AL, dma_high_order_count_byte OUT 05h, AL ; load high order count byte ;....................................................................... ; ; unmask channel ;....................................................................... MOV AL, 02h ; release channel 2 OUT 0Ah, AL ; DMA-1 Mask Register Bit ; command 2d = 2h = 0000 0010b ; clear mask channel 2 ;....................................................................... ; ; enable dma1 ;....................................................................... MOV AL, 10h ; OUT 08h, AL ; DMA-1 Command Register Port ; 10d = 0Ah = 0001 0000b ; enable DMA sti ; enable interrupts ret ; dma_access endp ; ;........................................................................ end start ; end program ------------------------------------------------------------------------ Follow Ups:  Disk access... - Jeffrey 2000-02-16 (0)  Re: Disk access... - ports 2000-02-22 (0)  Re: Disk access... - ////// 2000-02-17 (0)  You could try... - Bikram 2000-02-17 (0)   Hard Drive I/O isn't hard at all - Untitled 2000-02-17 (0)    Wha ?? Read... - Bikram 2000-02-17 (0)     Ports Info - Darius 2000-02-19 (0)      Re: Ports Info - Bikram 2000-02-20 (0)       Just rambling mostly - Darius 2000-02-20 (0) ------------------------------------------------------------------------ click here to post a reply to this message If you find that this message does NOT belong in this forum, please report it to the webmaster by clicking HERE. FAQSearchDisclaimer/Privacy StatementSubmit/update file or linkDesign by Björn Fogelberg©2000 Synchron DataAll rights reservedModified 2000-02-24