home *** CD-ROM | disk | FTP | other *** search
/ Falcon 030 Power 2 / F030_POWER2.iso / ST_STE / MAGS / TOXIC_14.ARJ / toxic_14 / TOXIC_14.D_2 / LEONARD / LEO_ST.ZIP / ST_PC / HD_EMUL / HARDDISK.S < prev    next >
Text File  |  1995-06-16  |  10KB  |  538 lines

  1.  
  2. ;****************************************************************
  3. ;*                                *
  4. ;*    HARD-DISK.                        *
  5. ;*    Simule un disque dur sur ST grace a un disk dur PC    *
  6. ;*    et une liaison 4 bits paralelle.            *
  7. ;*                                *
  8. ;*    Code and Idea by Leonard/OXYGENE.            *
  9. ;*                                *
  10. ;****************************************************************
  11.  
  12.  
  13. HARD_DRIVE    equ    ('E'-65)
  14.  
  15.  
  16. ; Tailles utilisateurs.
  17.  
  18.  
  19. ;Tailles systems
  20. HEADER_SIZE    equ    8
  21. CHAR_BIT    equ    8
  22. CRCPOLY        equ    $EDB88320
  23.  
  24. ; Vecteurs de traitement des secteurs de bas niveau sur ST.
  25. HDV_BPB        equ    $472
  26. HDV_RW        equ    $476
  27. HDV_MCH        equ    $47e
  28.  
  29.  
  30. ; COMMANDES de l'emulateur de disk au PC.
  31. CMD_HARD_INIT    equ    0
  32. CMD_READ_SECTOR    equ    1
  33.  
  34.  
  35.  
  36.  
  37.     section    text
  38.  
  39.  
  40.  
  41.         movea.l    sp,a5
  42.         lea    my_stack,a7
  43.         move.l    4(a5),a5
  44.         move.l    #256,d7
  45.         add.l    $c(a5),d7
  46.         add.l    $14(a5),d7
  47.         add.l    $1c(a5),d7
  48.         move.l    d7,prg_size
  49.         move.l    d7,-(sp)
  50.         pea    (a5)
  51.         clr.w    -(sp)
  52.         move.w    #$4a,-(sp)
  53.         trap    #1
  54.         lea    12(sp),sp
  55.  
  56.  
  57.         lea    txt_intro,a0
  58.         bsr    print
  59.  
  60.  
  61.     ; Passage en superviseur.
  62.         clr.l    -(sp)
  63.         move.w    #32,-(sp)
  64.         trap    #1
  65.         addq.l    #6,sp
  66.  
  67.  
  68.  
  69.         move.l    $4c2.w,d0
  70.             btst.l    #HARD_DRIVE,d0
  71.         beq.s    init
  72.  
  73.         lea    txt_already,a0
  74.         bsr    print
  75.         bsr    wait_key
  76.         bra    gemdos_error
  77.  
  78.  
  79.  
  80. init:
  81.  
  82.  
  83.  
  84.  
  85.     ;*************************************************************
  86.     ; On demande au PC d'initialiser l'emulateur disk.
  87.     ;*************************************************************
  88.         move.w    #CMD_HARD_INIT,info_block
  89.         moveq    #HEADER_SIZE,d0
  90.         bsr    pc_send_block
  91.         beq.s    .ok
  92.  
  93. .pc_error    lea    txt_pcout,a0
  94.         bsr    print
  95.         bsr    wait_key
  96.         bra    gemdos_error
  97.  
  98. .ok:
  99.         lea    ret_value,a0
  100.         moveq    #HEADER_SIZE,d0
  101.         bsr    pc_receive_block
  102.         bne.s    .pc_error
  103.         tst.l    ret_value
  104.         bne.s    .pc_error
  105.  
  106.  
  107.  
  108.     ;****************************************************************
  109.     ; L'emulateur sur le PC est pret, on peut installer les vecteurs.
  110.     ;****************************************************************
  111.  
  112.         bsr    calc_crctable
  113.         bsr    built_fast_table
  114.  
  115.         move.l    (HDV_BPB).w,bpb_jmp+2
  116.         move.l    #my_bpb,(HDV_BPB).w
  117.         move.l    (HDV_RW).w,rw_jmp+2
  118.         move.l    #my_rw,(HDV_RW).w
  119.         move.l    (HDV_MCH).w,mch_jmp+2
  120.         move.l    #my_mch,(HDV_MCH).w
  121.         move.l    #trap15,($80+15*4).w
  122.         move.l    $4c2.w,d0
  123.         bset.l    #HARD_DRIVE,d0
  124.         move.l    d0,$4c2.w
  125.  
  126.  
  127.     ; On revient au GEM en reservant la place.
  128.         bra    gemdos_ok
  129.  
  130.  
  131.  
  132. ;********************************************************
  133. ;*                            *
  134. ;*    Get BPB.                    *
  135. ;*                            *
  136. ;********************************************************
  137.  
  138. bpb_jmp        jmp    $0
  139. my_bpb:
  140.         cmp.w    #HARD_DRIVE,4(sp)
  141.         bne.s    bpb_jmp
  142.  
  143.         ;move.l    #bpbemul,d0
  144.         rts
  145.  
  146.  
  147.  
  148.  
  149. ;********************************************************
  150. ;*                            *
  151. ;*    Read-Write.                    *
  152. ;*                            *
  153. ;********************************************************
  154. rw_jmp        jmp    $0
  155. my_rw:
  156.         cmp.w    #HARD_DRIVE,14(sp)
  157.         bne.s    rw_jmp
  158.  
  159.         move.w    4(sp),d0
  160.         btst    #0,d0
  161.         beq.s    .read
  162.  
  163.         moveq    #-36,d0            ; ERROR: Interdit d'ecrire.
  164.         rts
  165.  
  166. .read:
  167.  
  168.         moveq    #0,d0
  169.         move.w    10(sp),d1        ; Nb de secteurs.
  170.         move.w    12(sp),d0        ; Secteur logique.
  171.         lsl.l    #8,d0
  172.         add.l    d0,d0            ; *512=offset en octets.
  173.  
  174.         move.w    #CMD_READ_SECTOR,info_block
  175.         move.l    d0,info_block+2
  176.         move.w    d1,info_block+6
  177.         moveq    #HEADER_SIZE,d0
  178.         bsr    pc_send_block        ; Envoie la demande de lecture.
  179.         beq.s    .ok
  180.  
  181.         moveq    #-11,d0            ; Erreur de lecture.
  182.         rts
  183.  
  184. .ok:
  185.  
  186.         move.l    6(sp),a0        ; Adresse de lecture
  187.         moveq    #0,d0
  188.         move.w    10(sp),d0        ; nb de secteurs.
  189.         lsl.l    #8,d0
  190.         add.l    d0,d0            ; *512=taille block en octets.
  191.         bsr    pc_receive_block
  192.         beq.s    .okr
  193.  
  194.         moveq    #-11,d0            ; Erreur de lecture.
  195.         rts
  196.  
  197. .okr:
  198.         moveq    #0,d0
  199.         rts
  200.  
  201.  
  202.  
  203.  
  204.  
  205. ;********************************************************
  206. ;*                            *
  207. ;*    Media Change.                    *
  208. ;*                            *
  209. ;********************************************************
  210. mch_jmp:    jmp    $0
  211. my_mch:        cmp.w    #HARD_DRIVE,4(sp)
  212.         bne.s    mch_jmp
  213.         move.w    changed,d0
  214.         clr.w    changed
  215.         rts
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223. ;************************************************************************
  224.  
  225.  
  226. ;**********************************************
  227. ; Init le disk dur.
  228. ;**********************************************
  229. r_hard_init    move.w    d0,info_block        ; commande.
  230.         moveq    #HEADER_SIZE,d0
  231.         bsr    pc_send_block
  232.         rts
  233.  
  234.  
  235.  
  236.  
  237. ;**********************************************
  238. ; Trap pour passer en sr = $2700
  239. ;**********************************************
  240. trap15        move.w    #$2700,(sp)
  241.         rte
  242.  
  243.  
  244. ;**********************************************
  245. ; SEND BLOCK to PC.
  246. ;**********************************************
  247. pc_send_block
  248.         ; Envoie de d0 octets a partir de info_block au PC.
  249.  
  250.  
  251.         rts
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. ;****************************************************************
  259. ;*                                *
  260. ;*    BAS NIVEAU.                        *
  261. ;*    PC_RECEIVE_BLOCK                    *
  262. ;*                                *
  263. ;*    Recoie D0 bytes a l'adresse A0.                *
  264. ;*    En retour, D0=0  si pas d'erreur.            *
  265. ;*           D0>0 si coupure de liaison            *
  266. ;*           D0=-1 si erreur CRC32.            *
  267. ;*                                *
  268. ;****************************************************************
  269. pc_receive_block
  270.         ; Reception de D0 bytes a partir de l'adresse a0.
  271.  
  272.         move.l    d0,rec_size
  273.         move.l    a0,rec_ad
  274.  
  275.         move.w    sr,-(sp)
  276.         trap    #15            ; SR=2700
  277.  
  278.         movea.w    #$8800,a6        ; Adresse PSG
  279.  
  280.  
  281.     ; Sauve la config du MFP et PSG
  282.         move.b    $fffffa05.w,port_dir
  283.         move.b    #7,(a6)
  284.         move.b    (a6),psg_7
  285.         move.b    #$e,(a6)
  286.         move.b    (a6),psg_e
  287.  
  288.  
  289.     ; Set la config pour recevoir.
  290.         move.l    #$0700c000,(a6)
  291.         move.l    #$0e000700,(a6)
  292.         bclr.b    #0,$fffffa05.w        ; Port Centronics en entrée.
  293.  
  294.  
  295.         move.w    d0,d7            ; Taille en octets.
  296.         subq.w    #1,d7            ; -1 pour DBF.
  297.  
  298.  
  299.         lea    $fffffa01.w,a5
  300.         moveq    #0,d6            ; Bit busy: 0
  301.  
  302.  
  303.  
  304.     ; On recoit le block.
  305. .sw1:        moveq    #-1,d5            ; Time out
  306. .w1:        btst    d6,(a5)
  307.     ;    bne.s    .w1
  308.         dbeq    d5,.w1
  309.         bne    .time_out
  310.         move.b    (a6),d0
  311.         lsl.b    #4,d0
  312.         moveq    #$0f,d2
  313.  
  314. .w2:        btst    d6,(a5)
  315.     ;    beq.s    .w2
  316.         dbne    d5,.w1
  317.         beq    .time_out
  318.         and.b    (a6),d2
  319.         or.b    d2,d0
  320.         move.b    d0,(a0)+        ; ecrit l'octet.
  321.         dbf    d7,.sw1
  322.  
  323.         lea    vcrc32,a0
  324.         moveq    #4-1,d7
  325.  
  326.  
  327.     ; Puis on recoit le CRC32.
  328. .sw2:        moveq    #-1,d5            ; Time out
  329. .w3:        btst    d6,(a5)
  330.     ;    bne.s    .w3
  331.         dbeq    d5,.w3
  332.         bne    .time_out
  333.         move.b    (a6),d0
  334.         lsl.b    #4,d0
  335.         moveq    #$0f,d2
  336.  
  337. .w4:        btst    d6,(a5)
  338.     ;    beq.s    .w4
  339.         dbne    d5,.w4
  340.         beq    .time_out
  341.         and.b    (a6),d2
  342.         or.b    d2,d0
  343.         move.b    d0,(a0)+        ; ecrit l'octet.
  344.         dbf    d7,.sw2
  345.  
  346.  
  347.  
  348.     ; On calcul le CRC32
  349.         move.l    rec_size,d0
  350.         move.l    rec_ad,a0
  351.         bsr    calc_crc32
  352.  
  353.     ; Et on compare avec le recu.
  354.         moveq    #-1,d7
  355.         cmp.l    vcrc32,d0
  356.         bne.s    .time_out
  357.  
  358.         moveq    #0,d7
  359.  
  360. .time_out:
  361.  
  362.  
  363.  
  364.     ; On retablit le port.
  365.         move.b    #7,(a6)
  366.         move.b    psg_7,2(a6)
  367.         move.b    #$e,(a6)
  368.         move.b    psg_e,2(a6)
  369.         move.b    port_dir,$fffffa05.w
  370.  
  371.  
  372.         move.w    (sp)+,sr        ; Retour a l'ancien mode.
  373.  
  374.         moveq    #0,d0
  375.         move.w    d7,d0
  376.         tst.w    d0
  377.         rts
  378.  
  379.  
  380.  
  381. ;************************************************************************
  382.  
  383. calc_crc32
  384. ; Input: A0: buffer to check, D0: Size in bytes.
  385. ; Output: D0: CRC32
  386.     move.l    d0,d7
  387.     moveq    #0,d0            ; CRC
  388.     lea    crc_table,a1
  389. .loop:    moveq    #0,d1
  390.     move.b    (a0)+,d1
  391.     eor.b    d0,d1
  392.     add.w    d1,d1
  393.     add.w    d1,d1
  394.     move.l    0(a1,d1.w),d1
  395.     lsr.l    #CHAR_BIT,d0
  396.     eor.l    d1,d0
  397.     subq.l    #1,d7
  398.     bne.s    .loop
  399.     rts
  400.  
  401.  
  402. built_fast_table
  403.         lea    fast_table,a0
  404.         moveq    #0,d0
  405. .loop:        move.w    d0,d1
  406.         move.w    d0,d2
  407.         andi.w    #$0f00,d1
  408.         andi.w    #$000f,d2
  409.         lsr.w    #4,d1
  410.         or.w    d1,d2
  411.         move.b    d2,(a0)+
  412.         addq.w    #1,d0
  413.         cmpi.w    #$8000,d0
  414.         bne.s    .loop
  415.         rts
  416.  
  417.  
  418.  
  419.  
  420. calc_crctable
  421.     lea    crc_table,a0
  422.     moveq    #0,d0
  423. .loop:    move.l    d0,d1
  424.     rept    CHAR_BIT
  425.     lsr.l    #1,d1
  426.     bcc.s    *+2+6
  427.     eori.l    #CRCPOLY,d1
  428.     endr
  429.     move.l    d1,(a0)+
  430.     addq.b    #1,d0
  431.     bne.s    .loop
  432.     rts
  433.  
  434.  
  435. gemdos_error:
  436.         clr.w    -(sp)
  437.         trap    #1
  438.  
  439.  
  440. gemdos_ok
  441.         clr.w    -(sp)
  442.         move.l    prg_size,-(sp)
  443.         move.w    #$31,-(sp)
  444.         trap    #1
  445.  
  446.  
  447.  
  448.  
  449. print:        pea    (a0)
  450.         move.w    #9,-(sp)
  451.         trap    #1
  452.         addq.l    #6,sp
  453.         rts
  454.  
  455. wait_key:
  456.         move.w    #7,-(sp)
  457.         trap    #1
  458.         addq.w    #2,sp
  459.         rts
  460.  
  461.  
  462. ;***************************************************************************
  463. ;***************************************************************************
  464.  
  465.     section    data
  466.  
  467. changed        dc.w    2    ; Flag premier changement pour MEDIA-CHG.
  468.  
  469.  
  470. txt_intro    dc.b    27,'E'
  471.         dc.b    'HARD-DISK emulator.',10,13
  472.         dc.b    '(C)OXYGENE 1995 by Leonard.',10,13
  473.         dc.b    0
  474. txt_pcout    dc.b    'INIT error: PC not responding',10,13
  475.         dc.b    'for initialising hard-disk.',0
  476. txt_already    dc.b    'ERROR: Emulated hard disk already',10,13
  477.         dc.b    'mounted on drive ',(HARD_DRIVE+'A'),':',0
  478.  
  479.  
  480.         even
  481.  
  482. ;***************************************************************************
  483. ;***************************************************************************
  484.  
  485.     section    bss
  486.  
  487.         ds.l    64
  488. my_stack:
  489. prg_size    ds.l    1
  490. rec_size    ds.l    1
  491. rec_ad        ds.l    1
  492. send_size    ds.l    1
  493. send_ad        ds.l    1
  494. vcrc32        ds.l    1
  495. crc_table    ds.l    256
  496.  
  497. port_dir    ds.b    1
  498. psg_7        ds.b    1
  499. psg_e        ds.b    1
  500.         even
  501. fast_table    ds.b    $8000        ; Fast-Table de 32Kos
  502. ret_value    ds.b    HEADER_SIZE
  503. info_block    ds.b    HEADER_SIZE
  504.         ds.b    512
  505.  
  506.  
  507.         END
  508.  
  509.  
  510. ; teste de routine qui blinde en lecture avec time out !!!
  511. ; try to beat this ha ha ha ha...
  512.  
  513.  
  514.         move.w    d0,d7        ; Nb octets (pas de -1, meme pour DBF)
  515.         lea    fast_table,a1
  516.         moveq    #-1,d6        ; Valeur initiale TIME-OUT.
  517.         bra.s    .w2
  518.  
  519.  
  520.     ; Main loop:
  521. .w1        move.b    (a6),d0
  522.         dbmi.s    d6,.w1        ; dec time out + wait busy
  523.         bpl.s    .out        ; time out ??
  524.         move.b    0(a1,d0.w),(a0)+
  525. .w2        move.w    (a6),d0    
  526.         dbpl.s    d6,.w2        ; dec time out + wait busy.
  527.         dbmi.s    d7,.w1        ; 
  528.  
  529.  
  530.     ; Sortie:
  531. .out:        addq.w    #1,d7        ; If d7=-1 alors d7=0, ok.
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.