Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;### fdc.inc ###  Menuetos floppy stuff.
  2. ;Version 0.2: Write individual tracks. / Sync ramdisk <-> floppy
  3. ;Version 0.1: Write full ramdisk to floppy.
  4. ;£loppyright Tolle.
  5.  
  6. ;depends on:
  7. ;restorefatchain
  8. ;memmove
  9. ;Int 6 (sys32.inc) should call fdc_irq func.
  10. ;The ramdisk should be at 0x100000
  11.  
  12. ;Keeping track of the tracks.
  13. iglobal
  14.   cylinder        db 0
  15.   sector          db 1
  16.   head            db 0
  17.  
  18.   ;Memory and dma variables.
  19.   fdcmem          dd 0x100000
  20.   cpymem          dd 0x100000
  21.   dmamem          dd 0x100000
  22. endg
  23.  
  24. uglobal
  25.   dmasize         db 0x0
  26.   dmamode         db 0x0
  27. endg
  28.  
  29. iglobal
  30.   ;function pointers.
  31.   fdc_irq_func    dd fdc_null
  32.   fdc_pump_func   dd fdc_null
  33. endg
  34.  
  35. uglobal
  36.   ;General stuff
  37.   fdc_st0         db 0            ;status register 0 of last resultphase.
  38.   fdc_mutex       db 0            ;wait in line. (Block calling app)
  39.   fdc_callspending        db 0            ;mystery sauce
  40.   fdc_settings    dd 0            ;bitfield.
  41. endg
  42.                                 ;Bit 0  enable direct file write [yes/no]
  43.  
  44. fdc_set:                                ;ebx: fdc_settings bitfield.
  45. mov [fdc_settings],ebx
  46. ret
  47.  
  48. fdc_get:                                ;returns fdc_settings in ecx
  49. mov ecx, [fdc_settings]
  50. ret
  51.  
  52. fdc_init:                               ;start with clean tracks.
  53.         mov edi,0xD201
  54.         mov al,0
  55.         mov ecx,160
  56.         rep stosb
  57. ret
  58.  
  59. fdc_filesave:                   ;ebx: cluster to be saved.
  60.         pusha                   ;returns immediately. does not trigger a write.
  61.         mov eax,ebx
  62.         add eax,31
  63.         mov bl,18
  64.         div bl
  65.         mov ah,0
  66.         add eax,0xD201
  67.         mov [eax],byte 1                ;This track is now dirty.
  68.         popa
  69. ret
  70.  
  71.  
  72. fdc_writeramdisk:                       ;mark all tracks as dirty.
  73.         mov edi,0xD201
  74.         mov al,1
  75.         mov ecx,160
  76.         rep stosb
  77.         jmp fdc_commitflush
  78. fdc_commitfile:                 ;flush dirty tracks to floppy
  79.         test [fdc_settings],1   ;...but only if this is really wanted by the user.
  80.         je fdc_commitend
  81. fdc_commitflush:
  82.         cmp [fdc_callspending],5
  83.         je fdc_commitend
  84.         inc [fdc_callspending]
  85.         cmp [fdc_callspending],1
  86.         je fdc_commitonce
  87.         fdc_commitend:
  88. ret
  89.  
  90. fdc_commitonce:                 ;One at a time.
  91.         .stall:
  92. cli
  93.         cmp [fdc_mutex],0
  94.         jne .stallret
  95.         mov [fdc_mutex],1
  96.         jmp .goahead
  97.         .stallret:
  98. sti
  99.         jmp .stall
  100.         .goahead:
  101. sti
  102.  
  103. fdc_commitramdisk:
  104.  
  105.         call restorefatchain
  106.                                 ;Move the bootsector to a safe place.
  107.         mov eax,0x100000
  108.         mov ebx,0xD000
  109.         mov ecx,512
  110.         call memmove
  111.                                 ;Always write the FAT table
  112.         mov eax,0xD201
  113.         mov [eax],byte 1
  114.         inc eax
  115.         mov [eax],byte 1
  116.  
  117.         mov [dmamode],0x4A      ;read from memory to floppy.
  118.         mov [dmasize],0x1               ;read 512 bytes sectors.
  119.         mov [fdc_irq_func],fdc_commitramdisk1
  120.         call fdc_floppy_on              ;start floppy A: moter starts interruptflow.
  121.         ret
  122. fdc_commitramdisk1:
  123.         mov [fdc_irq_func],fdc_recalibrate_result
  124.         mov [fdc_pump_func],fdc_commitramdisk2
  125.         call fdc_recalibrate            ;retract the head to cylinder 0, sector 1
  126.         ret
  127. fdc_commitramdisk2:
  128.         mov[head],0             ;set variables.
  129.         mov[cylinder],0
  130.         mov [sector],1
  131.         mov[cpymem],0x102400
  132.         mov [fdc_pump_func],fdc_fullpump
  133.         call fdc_write          ;fdc_write will continue interruptflow
  134. ret
  135.  
  136. fdc_fullpump:
  137.         add [dmamem],512
  138.         add [sector],1
  139.         cmp [sector],19
  140.         jne .clusterwrite
  141.         sub [dmamem],9216
  142.         mov eax,[cpymem]
  143.         mov ebx,[fdcmem]
  144.         mov ecx,9216
  145.         call memmove
  146.         add [cpymem],9216
  147.         cmp [head],0
  148.         je .nocylinderchange
  149.         add [cylinder],1
  150.         .nocylinderchange:
  151.         xor [head],1
  152.         cmp [cylinder],80
  153.         jne .noendofwrite
  154.         mov[fdc_irq_func],fdc_complete
  155.         call fdc_floppy_off
  156.         call fdc_init
  157.         jmp .end
  158.         .noendofwrite:
  159.         mov [sector],1
  160.         .clusterwrite:
  161.         xor eax,eax
  162.         mov al,[cylinder]
  163.         shl eax,1
  164.         add al,[head]
  165.         add eax,0xD201
  166.         mov bl,[eax]
  167.         cmp bl,1
  168.         jne fdc_fullpump
  169.         call fdc_write
  170.         .end:
  171. ret
  172.  
  173. fdc_write:
  174.         call fdc_program_dma
  175.         call fdc_seek
  176. ret
  177.  
  178. fdc_seek:
  179.         mov al, 0x0f
  180.         call fdc_write_reg
  181.         mov al,[head]
  182.         shl al,2
  183.         call fdc_write_reg
  184.         mov al,[cylinder]
  185.         call fdc_write_reg
  186.         mov [fdc_irq_func],fdc_seek_result
  187. ret
  188.  
  189. fdc_seek_result:
  190.         call fdc_sensei
  191.         cmp al,[cylinder]
  192.         je .succes
  193.         call fdc_seek
  194.         jmp .end
  195.         .succes:
  196.         call fdc_write_sector
  197.         .end:
  198. ret
  199.  
  200. fdc_write_sector:
  201.         mov al,0x45             ;write sector command
  202. fdc_commandphase:
  203.         call fdc_write_reg
  204.         mov al,[head]
  205.         shl al,2
  206.         call fdc_write_reg
  207.         mov al,[cylinder]
  208.         call fdc_write_reg
  209.         mov al,[head]
  210.         call fdc_write_reg
  211.         mov al,[sector]
  212.         call fdc_write_reg
  213.         mov al,2                        ;Sector size (2 ~> 512 bytes)
  214.         call fdc_write_reg
  215.         mov al,18                       ;last sector on track.
  216.         call fdc_write_reg
  217.         mov al,27                       ;length of GAP3
  218.         call fdc_write_reg
  219.         mov al,0xFF             ;data length, ignored.
  220.         call fdc_write_reg
  221.         mov [fdc_irq_func],fdc_resultphase
  222. ret
  223.  
  224. fdc_resultphase:
  225.         call fdc_read_reg
  226.         mov [fdc_st0],al
  227.         mov cx,6
  228.         .readresult:
  229.         call fdc_read_reg
  230.         loop .readresult
  231.         and [fdc_st0],11000000b
  232.         cmp [fdc_st0],byte 0
  233.         jz .succes
  234.         call fdc_seek
  235.         jmp .end
  236.         .succes:
  237.         call [fdc_pump_func]
  238.         .end:
  239. ret
  240.  
  241. fdc_sensei:
  242.         mov al,0x08             ;get interrupt status command
  243.         call fdc_write_reg
  244.         call fdc_read_reg               ;get result in al;
  245.         and al,0x80
  246.         cmp al,0x80
  247.         je fdc_sensei           ;retry
  248.         call fdc_read_reg
  249. ret
  250.  
  251. fdc_program_dma:
  252.         mov al,0
  253.         out 0x0c,al     ; reset the flip-flop to a known state.
  254.         mov al,6                ; mask channel 2 so we can reprogram it.
  255.         out 0x0a,al
  256.         mov al,[dmamode]        ; 0x46 -> Read from floppy - 0x4A Write to floppy
  257.         out 0x0b,al
  258.         mov al,0
  259.         out 0x0c,al     ; reset the flip-flop to a known state.
  260.         mov eax,[dmamem]
  261.         out 0x04,al     ; set the channel 2 starting address to 0
  262.         shr eax,8
  263.         out 0x04,al
  264.         shr eax,8
  265.         out 0x81,al
  266.         mov al,0
  267.         out 0x0c, al    ; reset flip-flop
  268.         mov al, 0xff    ;set count (actual size -1)
  269.         out 0x5, al
  270.         mov al, [dmasize]       ;(0x1ff = 511 / 0x23ff =9215)
  271.         out 0x5,al
  272.         mov al,2
  273.         out 0xa,al
  274. ret
  275.  
  276. fdc_recalibrate:
  277.         mov al,0x07             ;calibrate command
  278.         call fdc_write_reg
  279.         mov al,0                        ;select drive 0
  280.         call fdc_write_reg
  281. ret
  282.  
  283. fdc_recalibrate_result:
  284.         mov al,0x08             ;get interrupt status command
  285.         call fdc_write_reg              ;send it
  286.         call fdc_read_reg               ;get command in al;
  287.         cmp al,0x80
  288.         je fdc_recalibrate_result
  289.         mov ah,al
  290.         call fdc_read_reg
  291.         cmp ah,0x70
  292.         jne .end
  293.         call fdc_recalibrate
  294.         jmp .reallyend
  295.         .end:
  296.         call [fdc_pump_func]
  297.         .reallyend:
  298. ret
  299.  
  300. fdc_busy:
  301.         .command_check:
  302.         mov dx,0x3F4
  303.         in al,dx
  304.         and al,0x10
  305.         cmp al,0x10
  306.         je .command_check
  307. ret
  308.  
  309. fdc_read_reg:
  310.         status_check:
  311.         mov dx,0x3F4
  312.         in al,dx
  313.         and al,0xc0
  314.         cmp al,0xc0
  315.         jne status_check
  316.         mov dx, 0x3F5
  317.         in al, dx
  318. ret
  319.  
  320. fdc_write_reg:
  321.         mov bl,al
  322.         .command_check:
  323.         mov dx,0x3F4
  324.         in al,dx
  325.         and al,0x80
  326.         cmp al,0x80
  327.         jne .command_check
  328.         mov al,bl
  329.         mov dx,0x3F5
  330.         out dx,al
  331. ret
  332.  
  333. fdc_floppy_off:
  334.         mov al,0xC
  335.         mov dx,0x3f2
  336.         out dx,al
  337. ret
  338.  
  339. fdc_floppy_on:
  340.         mov  dx,0x3f2
  341.         mov  al,0x0
  342.         out  dx,al
  343.         mov  al,0x1C
  344.         out  dx,al
  345.        
  346.         mov  eax,50
  347.         call delay_hs
  348. ret
  349.  
  350. fdc_complete:
  351.         mov eax,0xD000
  352.         mov ebx,0x100000
  353.         mov ecx,512
  354.         call memmove
  355.  
  356.         mov [fdc_irq_func],fdc_null
  357.         mov [fdc_mutex],0
  358.         dec [fdc_callspending]
  359.         cmp [fdc_callspending],0
  360.         je  .realyend
  361.         mov [fdc_mutex],1
  362.         call fdc_commitramdisk
  363.         .realyend:
  364. ret
  365.  
  366. fdc_irq:
  367.         call [fdc_irq_func]
  368. fdc_null:
  369. ret