Files
2024-02-19 00:25:23 -05:00

530 lines
18 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Picture>
<Picture: Logo>AboutAdvertisingAwardsContact usNewsMessageboards<Picture>
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.
<Picture>FAQSearchDisclaimer/Privacy StatementSubmit/update file or linkDesign by Björn Fogelberg©2000 Synchron DataAll rights reservedModified 2000-02-24<Picture: Infomagic_logo>