home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / amiga / frodov13.lha / src / 1541.asm next >
Assembly Source File  |  1995-02-22  |  35KB  |  1,755 lines

  1. *
  2. * 1541.asm - 1541-Emulation, Dateihandling
  3. *
  4. * Copyright (C) 1994-1995 by Christian Bauer
  5. *
  6.  
  7. *
  8. * Anmerkungen:
  9. * ------------
  10. *
  11. * Aufrufkonventionen:
  12. *  - Die Routinen IECOut#? und IECIn geben in d0 den Status zurⁿck.
  13. *    Dieser wird von den aufrufenden Routinen mit dem C64-Statusbyte
  14. *    ($90) verodert.
  15. *  - Die Routinen dⁿrfen nur d0-d1/a0-a1 verΣndern
  16. *
  17. * Funktionsweise:
  18. *  - Am IEC-Bus gibt es drei Sorten von GerΣten: Controller, Listener
  19. *    und Talker. Der Controller sind immer wir, zusΣtzlich k÷nnen wir
  20. *    wahlweise Talker und Listener sein. Es kann immer nur einen Talker
  21. *    und einen Listener geben (am echten IEC-Bus sind mehrere Listener
  22. *    erlaubt, aber hier nicht).
  23. *  - Die GerΣte, die angesprochen werden, sind entweder real am IEC-Kabel
  24. *    oder werden hier emuliert. Fⁿr jedes emulierte Laufwerk existiert
  25. *    eine eigene Datenstruktur (Drv?Data). Ein Zeiger darauf wird bei
  26. *    Talk/Listen in TalkerData/ListenerData gespeichert und steht den
  27. *    nachfolgend aufgerufenen Routinen zur Verfⁿgung, damit sich diese
  28. *    um das jeweils angesprochene Laufwerk kⁿmmern.
  29. *  - Bei GerΣten am Kabel wird #?Data nicht benutzt, da die Routinen
  30. *    dann die Daten im wesentlichen einfach an den IEC-Bus durchreichen
  31. *
  32. * EOI/EOF:
  33. *  - Im Gegensatz zum Amiga, wo der EOF-Zustand erst nach dem Lesen
  34. *    des letzten Bytes erkannt wird, wird beim IEC-Bus das EOF
  35. *    gleichzeitig mit dem letzten Byte gesendet. Daher verwenden die
  36. *    Leseroutinen einen Puffer, in dem immer ein Byte bereitsteht.
  37. *
  38. * Directory-Emulation:
  39. *  - Wird das Directory ge÷ffnet (Dateiname "$"), wird in T: eine
  40. *    temporΣre Datei angelegt, die vom Aufbau genau einem 1541-Directory
  41. *    entspricht und diese Datei ge÷ffnet. Sie kann dann mit den ganz
  42. *    normalen Lesebefehlen verarbeitet werden.
  43. *
  44. * InkompatibilitΣten/Verbesserungen:
  45. *  - Es kann nur ein Listener gleichzeitig aktiv sein
  46. *  - Kein Kommandokanal implementiert
  47. *  - Beim Empfang des Dateinamens sollte er auf Pufferⁿberlauf prⁿfen
  48. *
  49.  
  50.         MACHINE    68020
  51.  
  52.         INCLUDE    "exec/types.i"
  53.         INCLUDE    "exec/macros.i"
  54.         INCLUDE    "dos/dos.i"
  55.         INCLUDE    "dos/dosasl.i"
  56.         INCLUDE    "resources/misc.i"
  57.         INCLUDE    "hardware/cia.i"
  58.  
  59.         XREF    _SysBase
  60.         XREF    _DOSBase
  61.         XREF    _CiaBase
  62.         XREF    _MiscBase
  63.  
  64.         XREF    _ciaaprb
  65.         XREF    _ciaaddrb
  66.  
  67.         XDEF    Open1541
  68.         XDEF    Close1541
  69.         XDEF    ChangedDirs
  70.         XDEF    CloseIEC
  71.         XDEF    ChangedIEC
  72.         XDEF    IECOut
  73.         XDEF    IECOutATN
  74.         XDEF    IECOutSec
  75.         XDEF    IECIn
  76.         XDEF    IECSetATN
  77.         XDEF    IECRelATN
  78.         XDEF    IECTurnaround
  79.         XDEF    IECRelease
  80.         XDEF    IECIsOpen
  81.  
  82.         XDEF    Dir8        ;Prefs
  83.         XDEF    Dir9
  84.         XDEF    Dir10
  85.         XDEF    Dir11
  86.         XDEF    Drv8IsIEC
  87.         XDEF    Drv9IsIEC
  88.         XDEF    Drv10IsIEC
  89.         XDEF    Drv11IsIEC
  90.         XDEF    OtherIEC
  91.         XDEF    MapSlash
  92.  
  93.         SECTION    "CODE",CODE
  94.  
  95.  
  96. **
  97. ** Definitionen
  98. **
  99.  
  100. ; Datenstruktur fⁿr ein Laufwerk
  101.  STRUCTURE DRVDATA,0
  102.     BYTE    drv_ErrorCode        ;Letzter Fehlercode (ERR_#?)
  103.     BYTE    drv_ReadBuf        ;Byte-Puffer zum Lesen aus Dateien
  104.     BYTE    drv_IsIEC        ;Laufwerk wird ⁿber IEC-Kabel angesprochen
  105.     BYTE    pad0
  106.     STRUCT    drv_Handles,16*4    ;FileHandles fⁿr alle 16 SekundΣradressen
  107.     APTR    drv_NamePtr        ;Zeiger in Dateinamen, fⁿr Open/IECOut
  108.     APTR    drv_ErrorPtr        ;Zeiger in Fehlermeldung
  109.     APTR    drv_Lock        ;Lock des Verzeichnisses des Laufwerks
  110.  LABEL drv_SIZEOF
  111.  
  112. ; Register (mⁿssen mit den Definitionen in 6510.asm ⁿbereinstimmen!)
  113. RAMPTR        EQUR    a4    ;Zeiger auf C64-RAM
  114.  
  115. ; C64-Status-Codes
  116. ST_OK        = 0    ;Alles klar
  117. ST_READ_TIMEOUT    = $02    ;Timeout beim Lesen
  118. ST_TIMEOUT    = $03    ;Timeout
  119. ST_EOF        = $40    ;End of file
  120. ST_NOTPRESENT    = $80    ;Device not present
  121.  
  122. ; IEC-Befehlscodes
  123. CMD_DATA    = $60
  124. CMD_CLOSE    = $e0
  125. CMD_OPEN    = $f0
  126.  
  127. ; Fehlercodes (genauer: Die Nummer des zugeh. Fehlertextes)
  128. ERR_OK        = 0    ;00: OK
  129. ERR_STARTUP    = 1    ;Einschaltmeldung
  130. ERR_FILENOTFOUND = 2    ;62: FILE NOT FOUND
  131. ERR_NOCHANNEL    = 3    ;70: NO CHANNEL
  132. ERR_SYNTAX33    = 4    ;33: SYNTAX ERROR (Wildcards beim Schreiben)
  133.  
  134. ; Makros fⁿr IEC-Kabel
  135. DATA_HI        MACRO
  136.         bclr    #5,_ciaaprb
  137.         ENDM
  138.  
  139. DATA_LO        MACRO
  140.         bset    #5,_ciaaprb
  141.         ENDM
  142.  
  143. CLOCK_HI    MACRO
  144.         bclr    #4,_ciaaprb
  145.         ENDM
  146.  
  147. CLOCK_LO    MACRO
  148.         bset    #4,_ciaaprb
  149.         ENDM
  150.  
  151. ATN_HI        MACRO
  152.         bclr    #3,_ciaaprb
  153.         ENDM
  154.  
  155. ATN_LO        MACRO
  156.         bset    #3,_ciaaprb
  157.         ENDM
  158.  
  159. LINE_RELEASE    MACRO
  160.         ATN_HI
  161.         bsr    Wait40us
  162.         CLOCK_HI
  163.         DATA_HI
  164.         ENDM
  165.  
  166. ; Data -> Carry, Clock -> Negative
  167. GET_DATA_CLOCK    MACRO
  168. \@1$        move.b    _ciaaprb,d0
  169.         cmp.b    _ciaaprb,d0
  170.         bne    \@1$
  171.         add.b    d0,d0
  172.         ENDM
  173.  
  174. WAIT_CLOCK_HI    MACRO
  175. \@1$        GET_DATA_CLOCK
  176.         bpl    \@1$
  177.         ENDM
  178.  
  179. WAIT_CLOCK_LO    MACRO
  180. \@1$        GET_DATA_CLOCK
  181.         bmi    \@1$
  182.         ENDM
  183.  
  184. WAIT_DATA_HI    MACRO
  185. \@1$        GET_DATA_CLOCK
  186.         bcc    \@1$
  187.         ENDM
  188.  
  189. WAIT_DATA_LO    MACRO
  190. \@1$        GET_DATA_CLOCK
  191.         bcs    \@1$
  192.         ENDM
  193.  
  194.  
  195. **
  196. ** 1541-Emulation starten
  197. **
  198.  
  199. ; Einschaltmeldung bereitstellen
  200. Open1541    move.b    #ERR_STARTUP,Drv8Data+drv_ErrorCode
  201.         move.b    #ERR_STARTUP,Drv9Data+drv_ErrorCode
  202.         move.b    #ERR_STARTUP,Drv10Data+drv_ErrorCode
  203.         move.b    #ERR_STARTUP,Drv11Data+drv_ErrorCode
  204.  
  205. ; Locks der Verzeichnisse holen
  206.         move.l    _DOSBase,a6
  207.         bra    OpenLocks
  208.  
  209.  
  210. **
  211. ** 1541-Emulation beenden
  212. **
  213.  
  214. ; Alle Dateien schlie▀en
  215. Close1541    move.l    _DOSBase,a6
  216.  
  217.         lea    Drv8Data+drv_Handles,a2
  218.         bsr    FreeHandles
  219.         lea    Drv9Data+drv_Handles,a2
  220.         bsr    FreeHandles
  221.         lea    Drv10Data+drv_Handles,a2
  222.         bsr    FreeHandles
  223.         lea    Drv11Data+drv_Handles,a2
  224.         bsr    FreeHandles
  225.  
  226. ; Alle Locks freigeben
  227.         bsr    FreeLocks
  228.  
  229. ; TemporΣre Datei l÷schen
  230.         move.l    #TempFileName,d1
  231.         JMPLIB    DeleteFile
  232.  
  233. FreeHandles    moveq    #15,d7        ;16 KanΣle
  234. 2$        move.l    (a2)+,d1
  235.         beq    1$
  236.         clr.l    -4(a2)        ;FileHandle l÷schen
  237.         JSRLIB    Close
  238. 1$        dbra    d7,2$
  239.         rts
  240.  
  241.  
  242. **
  243. ** Die Verzeichnisse haben sich geΣndert: Neue Locks holen
  244. **
  245.  
  246. ChangedDirs    move.l    _DOSBase,a6
  247.         bsr    FreeLocks
  248.         bra    OpenLocks
  249.  
  250.  
  251. **
  252. ** IEC-Einstellungen wurden verΣndert
  253. ** Rⁿckgabe: d0=0 Alles OK
  254. **           d0=1 Parallelport belegt
  255. **           d0=2 Kein Timer frei
  256. **
  257.  
  258. ; Einstellungen ⁿbertragen
  259. ChangedIEC    moveq    #0,d1
  260.         move.w    Drv8IsIEC,d0
  261.         or.b    d0,d1
  262.         move.b    d0,Drv8Data+drv_IsIEC
  263.         move.w    Drv9IsIEC,d0
  264.         or.b    d0,d1
  265.         move.b    d0,Drv9Data+drv_IsIEC
  266.         move.w    Drv10IsIEC,d0
  267.         or.b    d0,d1
  268.         move.b    d0,Drv10Data+drv_IsIEC
  269.         move.w    Drv11IsIEC,d0
  270.         or.b    d0,d1
  271.         move.b    d0,Drv11Data+drv_IsIEC
  272.         or.w    OtherIEC,d1
  273.  
  274. ; IEC ÷ffnen, wenn mindestens ein GerΣt mit IEC laufen soll,
  275. ; sonst schlie▀en
  276.         tst.b    d1
  277.         beq    CloseIEC
  278.         bra    OpenIEC
  279.  
  280.  
  281. **
  282. ** Auf Benutzung des IEC-Kabels vorbereiten
  283. ** Rⁿckgabe: d0=0 Alles OK
  284. **           d0=1 Parallelport belegt
  285. **           d0=2 Kein Timer frei
  286. **
  287.  
  288. OpenIEC        move.l    a6,-(sp)
  289.         tst.b    IECIsOpen    ;Kann auch mehrmals aufgerufen werden
  290.         bne    OIECOK
  291.  
  292. ; Parallelport belegen
  293.         move.l    _MiscBase,a6
  294.         moveq    #MR_PARALLELPORT,d0
  295.         lea    ParPortName,a1
  296.         JSRLIB    AllocMiscResource
  297.         tst.l    d0
  298.         bne    OIECNoPort
  299.  
  300.         move.b    #$00,_ciaaprb    ;Port inaktiv
  301.         move.b    #$38,_ciaaddrb    ;DDR konfigurieren
  302.  
  303. ; Timer A belegen
  304.         move.l    _CiaBase,a6
  305.         lea    TimerInterrupt,a1
  306.         moveq    #CIAICRB_TA,d0
  307.         JSRLIB    AddICRVector
  308.         tst.l    d0
  309.         bne    1$
  310.  
  311. ; Gelungen
  312.         move.b    #CIAICRB_TA,WhichTimer
  313.         move.b    #CIAICRF_TA,WhichTimerMask
  314.         move.l    #$bfe401,CiaTimerReg
  315.         move.l    #$bfee01,CiaControlReg
  316.         bra    3$
  317.  
  318. ; Nicht gelungen, dann Timer B probieren
  319. 1$        lea    TimerInterrupt,a1
  320.         moveq    #CIAICRB_TB,d0
  321.         JSRLIB    AddICRVector
  322.         tst.l    d0
  323.         bne    2$
  324.  
  325. ; Gelungen
  326.         move.b    #CIAICRB_TB,WhichTimer
  327.         move.b    #CIAICRF_TB,WhichTimerMask
  328.         move.l    #$bfe601,CiaTimerReg
  329.         move.l    #$bfef01,CiaControlReg
  330.         bra    3$
  331.  
  332. ; Nicht gelungen, dann Parallelport wieder freigeben
  333. 2$        move.b    #$00,_ciaaddrb    ;Port auf Eingabe
  334.  
  335.         move.l    _MiscBase,a6
  336.         moveq    #MR_PARALLELPORT,d0
  337.         JSRLIB    FreeMiscResource
  338.  
  339.         moveq    #2,d0        ;Kein Timer frei
  340.         move.l    (sp)+,a6
  341.         rts
  342.  
  343. ; Alles klar, Timer-Interrupt abschalten und Timer stoppen
  344. 3$        move.b    WhichTimerMask,d0
  345.         JSRLIB    AbleICR
  346.  
  347.         move.l    CiaControlReg,a0
  348.         and.b    #$80,(a0)
  349.  
  350.         st.b    IECIsOpen
  351. OIECOK        moveq    #0,d0        ;Alles OK
  352.         move.l    (sp)+,a6
  353.         rts
  354.  
  355. OIECNoPort    moveq    #1,d0        ;Parallelport belegt
  356.         move.l    (sp)+,a6
  357.         rts
  358.  
  359.  
  360. **
  361. ** Benutzung des IEC-Kabels beenden
  362. ** Rⁿckgabe: d0=0
  363. **
  364.  
  365. CloseIEC    tst.b    IECIsOpen
  366.         beq    1$
  367.  
  368.         move.b    #$00,_ciaaddrb    ;Port auf Eingabe
  369.  
  370.         move.l    a6,-(sp)    ;Parallelport freigeben
  371.         move.l    _MiscBase,a6
  372.         moveq    #MR_PARALLELPORT,d0
  373.         JSRLIB    FreeMiscResource
  374.  
  375.         move.l    CiaControlReg,a0 ;Timer stoppen
  376.         and.b    #$80,(a0)
  377.  
  378.         move.l    _CiaBase,a6
  379.         lea    TimerInterrupt,a1
  380.         move.b    WhichTimer,d0
  381.         JSRLIB    RemICRVector
  382.  
  383.         move.l    (sp)+,a6
  384.         clr.b    IECIsOpen
  385.  
  386. 1$        moveq    #0,d0
  387.         rts
  388.  
  389.  
  390. *
  391. * Locks freigeben
  392. *
  393.  
  394. FreeLocks    move.l