1,24 → 1,6 |
;### fdc.inc ### Menuetos floppy stuff. |
;Version 0.2: Write individual tracks. / Sync ramdisk <-> floppy |
;Version 0.1: Write full ramdisk to floppy. |
;£loppyright Tolle. |
|
;depends on: |
;restorefatchain |
;memmove |
;Int 6 (sys32.inc) should call fdc_irq func. |
;The ramdisk should be at 0x100000 |
|
;Keeping track of the tracks. |
iglobal |
cylinder db 0 |
sector db 1 |
head db 0 |
|
;Memory and dma variables. |
fdcmem dd 0x100000 |
cpymem dd 0x100000 |
dmamem dd 0x100000 |
;function pointers. |
fdc_irq_func dd fdc_null |
endg |
|
uglobal |
26,29 → 8,6 |
dmamode db 0x0 |
endg |
|
iglobal |
;function pointers. |
fdc_irq_func dd fdc_null |
fdc_pump_func dd fdc_null |
endg |
|
uglobal |
;General stuff |
fdc_st0 db 0 ;status register 0 of last resultphase. |
fdc_mutex db 0 ;wait in line. (Block calling app) |
fdc_callspending db 0 ;mystery sauce |
fdc_settings dd 0 ;bitfield. |
endg |
;Bit 0 enable direct file write [yes/no] |
|
fdc_set: ;ebx: fdc_settings bitfield. |
mov [fdc_settings],ebx |
ret |
|
fdc_get: ;returns fdc_settings in ecx |
mov ecx, [fdc_settings] |
ret |
|
fdc_init: ;start with clean tracks. |
mov edi,0xD201 |
mov al,0 |
68,302 → 27,47 |
popa |
ret |
|
|
fdc_writeramdisk: ;mark all tracks as dirty. |
mov edi,0xD201 |
mov al,1 |
mov ecx,160 |
rep stosb |
jmp fdc_commitflush |
fdc_commitfile: ;flush dirty tracks to floppy |
test [fdc_settings],1 ;...but only if this is really wanted by the user. |
je fdc_commitend |
fdc_commitflush: |
cmp [fdc_callspending],5 |
je fdc_commitend |
inc [fdc_callspending] |
cmp [fdc_callspending],1 |
je fdc_commitonce |
fdc_commitend: |
fdc_irq: |
call [fdc_irq_func] |
fdc_null: |
ret |
|
fdc_commitonce: ;One at a time. |
.stall: |
cli |
cmp [fdc_mutex],0 |
jne .stallret |
mov [fdc_mutex],1 |
jmp .goahead |
.stallret: |
sti |
jmp .stall |
.goahead: |
sti |
|
fdc_commitramdisk: |
|
save_image: |
call reserve_flp |
call restorefatchain |
;Move the bootsector to a safe place. |
mov eax,0x100000 |
mov ebx,0xD000 |
mov ecx,512 |
call memmove |
;Always write the FAT table |
mov eax,0xD201 |
mov [eax],byte 1 |
inc eax |
mov [eax],byte 1 |
|
mov [dmamode],0x4A ;read from memory to floppy. |
mov [dmasize],0x1 ;read 512 bytes sectors. |
mov [fdc_irq_func],fdc_commitramdisk1 |
call fdc_floppy_on ;start floppy A: moter starts interruptflow. |
ret |
fdc_commitramdisk1: |
mov [fdc_irq_func],fdc_recalibrate_result |
mov [fdc_pump_func],fdc_commitramdisk2 |
call fdc_recalibrate ;retract the head to cylinder 0, sector 1 |
ret |
fdc_commitramdisk2: |
mov[head],0 ;set variables. |
mov[cylinder],0 |
mov [sector],1 |
mov[cpymem],0x102400 |
mov [fdc_pump_func],fdc_fullpump |
call fdc_write ;fdc_write will continue interruptflow |
ret |
|
fdc_fullpump: |
add [dmamem],512 |
add [sector],1 |
cmp [sector],19 |
jne .clusterwrite |
sub [dmamem],9216 |
mov eax,[cpymem] |
mov ebx,[fdcmem] |
mov ecx,9216 |
call memmove |
add [cpymem],9216 |
cmp [head],0 |
je .nocylinderchange |
add [cylinder],1 |
.nocylinderchange: |
xor [head],1 |
cmp [cylinder],80 |
jne .noendofwrite |
mov[fdc_irq_func],fdc_complete |
call fdc_floppy_off |
call fdc_init |
jmp .end |
.noendofwrite: |
mov [sector],1 |
.clusterwrite: |
xor eax,eax |
mov al,[cylinder] |
shl eax,1 |
add al,[head] |
add eax,0xD201 |
mov bl,[eax] |
cmp bl,1 |
jne fdc_fullpump |
call fdc_write |
.end: |
ret |
|
fdc_write: |
call fdc_program_dma |
call fdc_seek |
ret |
|
fdc_seek: |
mov al, 0x0f |
call fdc_write_reg |
mov al,[head] |
shl al,2 |
call fdc_write_reg |
mov al,[cylinder] |
call fdc_write_reg |
mov [fdc_irq_func],fdc_seek_result |
ret |
|
fdc_seek_result: |
call fdc_sensei |
cmp al,[cylinder] |
je .succes |
call fdc_seek |
jmp .end |
.succes: |
call fdc_write_sector |
.end: |
ret |
|
fdc_write_sector: |
mov al,0x45 ;write sector command |
fdc_commandphase: |
call fdc_write_reg |
mov al,[head] |
shl al,2 |
call fdc_write_reg |
mov al,[cylinder] |
call fdc_write_reg |
mov al,[head] |
call fdc_write_reg |
mov al,[sector] |
call fdc_write_reg |
mov al,2 ;Sector size (2 ~> 512 bytes) |
call fdc_write_reg |
mov al,18 ;last sector on track. |
call fdc_write_reg |
mov al,27 ;length of GAP3 |
call fdc_write_reg |
mov al,0xFF ;data length, ignored. |
call fdc_write_reg |
mov [fdc_irq_func],fdc_resultphase |
ret |
|
fdc_resultphase: |
call fdc_read_reg |
mov [fdc_st0],al |
mov cx,6 |
.readresult: |
call fdc_read_reg |
loop .readresult |
and [fdc_st0],11000000b |
cmp [fdc_st0],byte 0 |
jz .succes |
call fdc_seek |
jmp .end |
.succes: |
call [fdc_pump_func] |
.end: |
ret |
|
fdc_sensei: |
mov al,0x08 ;get interrupt status command |
call fdc_write_reg |
call fdc_read_reg ;get result in al; |
and al,0x80 |
cmp al,0x80 |
je fdc_sensei ;retry |
call fdc_read_reg |
ret |
|
fdc_program_dma: |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov al,6 ; mask channel 2 so we can reprogram it. |
out 0x0a,al |
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy |
out 0x0b,al |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov eax,[dmamem] |
out 0x04,al ; set the channel 2 starting address to 0 |
shr eax,8 |
out 0x04,al |
shr eax,8 |
out 0x81,al |
mov al,0 |
out 0x0c, al ; reset flip-flop |
mov al, 0xff ;set count (actual size -1) |
out 0x5, al |
mov al, [dmasize] ;(0x1ff = 511 / 0x23ff =9215) |
out 0x5,al |
mov al,2 |
out 0xa,al |
ret |
|
fdc_recalibrate: |
mov al,0x07 ;calibrate command |
call fdc_write_reg |
mov al,0 ;select drive 0 |
call fdc_write_reg |
ret |
|
fdc_recalibrate_result: |
mov al,0x08 ;get interrupt status command |
call fdc_write_reg ;send it |
call fdc_read_reg ;get command in al; |
cmp al,0x80 |
je fdc_recalibrate_result |
mov ah,al |
call fdc_read_reg |
cmp ah,0x70 |
jne .end |
call fdc_recalibrate |
jmp .reallyend |
.end: |
call [fdc_pump_func] |
.reallyend: |
ret |
|
fdc_busy: |
.command_check: |
mov dx,0x3F4 |
in al,dx |
and al,0x10 |
cmp al,0x10 |
je .command_check |
ret |
|
fdc_read_reg: |
status_check: |
mov dx,0x3F4 |
in al,dx |
and al,0xc0 |
cmp al,0xc0 |
jne status_check |
mov dx, 0x3F5 |
in al, dx |
ret |
|
fdc_write_reg: |
mov bl,al |
.command_check: |
mov dx,0x3F4 |
in al,dx |
and al,0x80 |
cmp al,0x80 |
jne .command_check |
mov al,bl |
mov dx,0x3F5 |
out dx,al |
ret |
|
fdc_floppy_off: |
mov al,0xC |
mov dx,0x3f2 |
out dx,al |
ret |
|
fdc_floppy_on: |
mov dx,0x3f2 |
mov al,0x0 |
out dx,al |
mov al,0x1C |
out dx,al |
|
mov eax,50 |
call delay_hs |
ret |
|
fdc_complete: |
mov eax,0xD000 |
mov ebx,0x100000 |
mov ecx,512 |
call memmove |
|
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
mov esi,0x100000 |
call SeekTrack |
save_image_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
; call WriteSector |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_image_1 |
mov [FDD_Sector],1 |
inc [FDD_Head] |
cmp [FDD_Head],2 |
jne save_image_1 |
mov [FDD_Head],0 |
inc [FDD_Track] |
call SeekTrack |
cmp [FDD_Track],80 |
jne save_image_1 |
unnecessary_save_image: |
mov [fdc_irq_func],fdc_null |
mov [fdc_mutex],0 |
dec [fdc_callspending] |
cmp [fdc_callspending],0 |
je .realyend |
mov [fdc_mutex],1 |
call fdc_commitramdisk |
.realyend: |
popa |
mov [flp_status],0 |
ret |
|
fdc_irq: |
call [fdc_irq_func] |
fdc_null: |
ret |