home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Brotikasten
/
BROTCD01.iso
/
amiga
/
frodov13.lha
/
src
/
1541.asm
next >
Wrap
Assembly Source File
|
1995-02-22
|
35KB
|
1,755 lines
*
* 1541.asm - 1541-Emulation, Dateihandling
*
* Copyright (C) 1994-1995 by Christian Bauer
*
*
* Anmerkungen:
* ------------
*
* Aufrufkonventionen:
* - Die Routinen IECOut#? und IECIn geben in d0 den Status zurⁿck.
* Dieser wird von den aufrufenden Routinen mit dem C64-Statusbyte
* ($90) verodert.
* - Die Routinen dⁿrfen nur d0-d1/a0-a1 verΣndern
*
* Funktionsweise:
* - Am IEC-Bus gibt es drei Sorten von GerΣten: Controller, Listener
* und Talker. Der Controller sind immer wir, zusΣtzlich k÷nnen wir
* wahlweise Talker und Listener sein. Es kann immer nur einen Talker
* und einen Listener geben (am echten IEC-Bus sind mehrere Listener
* erlaubt, aber hier nicht).
* - Die GerΣte, die angesprochen werden, sind entweder real am IEC-Kabel
* oder werden hier emuliert. Fⁿr jedes emulierte Laufwerk existiert
* eine eigene Datenstruktur (Drv?Data). Ein Zeiger darauf wird bei
* Talk/Listen in TalkerData/ListenerData gespeichert und steht den
* nachfolgend aufgerufenen Routinen zur Verfⁿgung, damit sich diese
* um das jeweils angesprochene Laufwerk kⁿmmern.
* - Bei GerΣten am Kabel wird #?Data nicht benutzt, da die Routinen
* dann die Daten im wesentlichen einfach an den IEC-Bus durchreichen
*
* EOI/EOF:
* - Im Gegensatz zum Amiga, wo der EOF-Zustand erst nach dem Lesen
* des letzten Bytes erkannt wird, wird beim IEC-Bus das EOF
* gleichzeitig mit dem letzten Byte gesendet. Daher verwenden die
* Leseroutinen einen Puffer, in dem immer ein Byte bereitsteht.
*
* Directory-Emulation:
* - Wird das Directory ge÷ffnet (Dateiname "$"), wird in T: eine
* temporΣre Datei angelegt, die vom Aufbau genau einem 1541-Directory
* entspricht und diese Datei ge÷ffnet. Sie kann dann mit den ganz
* normalen Lesebefehlen verarbeitet werden.
*
* InkompatibilitΣten/Verbesserungen:
* - Es kann nur ein Listener gleichzeitig aktiv sein
* - Kein Kommandokanal implementiert
* - Beim Empfang des Dateinamens sollte er auf Pufferⁿberlauf prⁿfen
*
MACHINE 68020
INCLUDE "exec/types.i"
INCLUDE "exec/macros.i"
INCLUDE "dos/dos.i"
INCLUDE "dos/dosasl.i"
INCLUDE "resources/misc.i"
INCLUDE "hardware/cia.i"
XREF _SysBase
XREF _DOSBase
XREF _CiaBase
XREF _MiscBase
XREF _ciaaprb
XREF _ciaaddrb
XDEF Open1541
XDEF Close1541
XDEF ChangedDirs
XDEF CloseIEC
XDEF ChangedIEC
XDEF IECOut
XDEF IECOutATN
XDEF IECOutSec
XDEF IECIn
XDEF IECSetATN
XDEF IECRelATN
XDEF IECTurnaround
XDEF IECRelease
XDEF IECIsOpen
XDEF Dir8 ;Prefs
XDEF Dir9
XDEF Dir10
XDEF Dir11
XDEF Drv8IsIEC
XDEF Drv9IsIEC
XDEF Drv10IsIEC
XDEF Drv11IsIEC
XDEF OtherIEC
XDEF MapSlash
SECTION "CODE",CODE
**
** Definitionen
**
; Datenstruktur fⁿr ein Laufwerk
STRUCTURE DRVDATA,0
BYTE drv_ErrorCode ;Letzter Fehlercode (ERR_#?)
BYTE drv_ReadBuf ;Byte-Puffer zum Lesen aus Dateien
BYTE drv_IsIEC ;Laufwerk wird ⁿber IEC-Kabel angesprochen
BYTE pad0
STRUCT drv_Handles,16*4 ;FileHandles fⁿr alle 16 SekundΣradressen
APTR drv_NamePtr ;Zeiger in Dateinamen, fⁿr Open/IECOut
APTR drv_ErrorPtr ;Zeiger in Fehlermeldung
APTR drv_Lock ;Lock des Verzeichnisses des Laufwerks
LABEL drv_SIZEOF
; Register (mⁿssen mit den Definitionen in 6510.asm ⁿbereinstimmen!)
RAMPTR EQUR a4 ;Zeiger auf C64-RAM
; C64-Status-Codes
ST_OK = 0 ;Alles klar
ST_READ_TIMEOUT = $02 ;Timeout beim Lesen
ST_TIMEOUT = $03 ;Timeout
ST_EOF = $40 ;End of file
ST_NOTPRESENT = $80 ;Device not present
; IEC-Befehlscodes
CMD_DATA = $60
CMD_CLOSE = $e0
CMD_OPEN = $f0
; Fehlercodes (genauer: Die Nummer des zugeh. Fehlertextes)
ERR_OK = 0 ;00: OK
ERR_STARTUP = 1 ;Einschaltmeldung
ERR_FILENOTFOUND = 2 ;62: FILE NOT FOUND
ERR_NOCHANNEL = 3 ;70: NO CHANNEL
ERR_SYNTAX33 = 4 ;33: SYNTAX ERROR (Wildcards beim Schreiben)
; Makros fⁿr IEC-Kabel
DATA_HI MACRO
bclr #5,_ciaaprb
ENDM
DATA_LO MACRO
bset #5,_ciaaprb
ENDM
CLOCK_HI MACRO
bclr #4,_ciaaprb
ENDM
CLOCK_LO MACRO
bset #4,_ciaaprb
ENDM
ATN_HI MACRO
bclr #3,_ciaaprb
ENDM
ATN_LO MACRO
bset #3,_ciaaprb
ENDM
LINE_RELEASE MACRO
ATN_HI
bsr Wait40us
CLOCK_HI
DATA_HI
ENDM
; Data -> Carry, Clock -> Negative
GET_DATA_CLOCK MACRO
\@1$ move.b _ciaaprb,d0
cmp.b _ciaaprb,d0
bne \@1$
add.b d0,d0
ENDM
WAIT_CLOCK_HI MACRO
\@1$ GET_DATA_CLOCK
bpl \@1$
ENDM
WAIT_CLOCK_LO MACRO
\@1$ GET_DATA_CLOCK
bmi \@1$
ENDM
WAIT_DATA_HI MACRO
\@1$ GET_DATA_CLOCK
bcc \@1$
ENDM
WAIT_DATA_LO MACRO
\@1$ GET_DATA_CLOCK
bcs \@1$
ENDM
**
** 1541-Emulation starten
**
; Einschaltmeldung bereitstellen
Open1541 move.b #ERR_STARTUP,Drv8Data+drv_ErrorCode
move.b #ERR_STARTUP,Drv9Data+drv_ErrorCode
move.b #ERR_STARTUP,Drv10Data+drv_ErrorCode
move.b #ERR_STARTUP,Drv11Data+drv_ErrorCode
; Locks der Verzeichnisse holen
move.l _DOSBase,a6
bra OpenLocks
**
** 1541-Emulation beenden
**
; Alle Dateien schlie▀en
Close1541 move.l _DOSBase,a6
lea Drv8Data+drv_Handles,a2
bsr FreeHandles
lea Drv9Data+drv_Handles,a2
bsr FreeHandles
lea Drv10Data+drv_Handles,a2
bsr FreeHandles
lea Drv11Data+drv_Handles,a2
bsr FreeHandles
; Alle Locks freigeben
bsr FreeLocks
; TemporΣre Datei l÷schen
move.l #TempFileName,d1
JMPLIB DeleteFile
FreeHandles moveq #15,d7 ;16 KanΣle
2$ move.l (a2)+,d1
beq 1$
clr.l -4(a2) ;FileHandle l÷schen
JSRLIB Close
1$ dbra d7,2$
rts
**
** Die Verzeichnisse haben sich geΣndert: Neue Locks holen
**
ChangedDirs move.l _DOSBase,a6
bsr FreeLocks
bra OpenLocks
**
** IEC-Einstellungen wurden verΣndert
** Rⁿckgabe: d0=0 Alles OK
** d0=1 Parallelport belegt
** d0=2 Kein Timer frei
**
; Einstellungen ⁿbertragen
ChangedIEC moveq #0,d1
move.w Drv8IsIEC,d0
or.b d0,d1
move.b d0,Drv8Data+drv_IsIEC
move.w Drv9IsIEC,d0
or.b d0,d1
move.b d0,Drv9Data+drv_IsIEC
move.w Drv10IsIEC,d0
or.b d0,d1
move.b d0,Drv10Data+drv_IsIEC
move.w Drv11IsIEC,d0
or.b d0,d1
move.b d0,Drv11Data+drv_IsIEC
or.w OtherIEC,d1
; IEC ÷ffnen, wenn mindestens ein GerΣt mit IEC laufen soll,
; sonst schlie▀en
tst.b d1
beq CloseIEC
bra OpenIEC
**
** Auf Benutzung des IEC-Kabels vorbereiten
** Rⁿckgabe: d0=0 Alles OK
** d0=1 Parallelport belegt
** d0=2 Kein Timer frei
**
OpenIEC move.l a6,-(sp)
tst.b IECIsOpen ;Kann auch mehrmals aufgerufen werden
bne OIECOK
; Parallelport belegen
move.l _MiscBase,a6
moveq #MR_PARALLELPORT,d0
lea ParPortName,a1
JSRLIB AllocMiscResource
tst.l d0
bne OIECNoPort
move.b #$00,_ciaaprb ;Port inaktiv
move.b #$38,_ciaaddrb ;DDR konfigurieren
; Timer A belegen
move.l _CiaBase,a6
lea TimerInterrupt,a1
moveq #CIAICRB_TA,d0
JSRLIB AddICRVector
tst.l d0
bne 1$
; Gelungen
move.b #CIAICRB_TA,WhichTimer
move.b #CIAICRF_TA,WhichTimerMask
move.l #$bfe401,CiaTimerReg
move.l #$bfee01,CiaControlReg
bra 3$
; Nicht gelungen, dann Timer B probieren
1$ lea TimerInterrupt,a1
moveq #CIAICRB_TB,d0
JSRLIB AddICRVector
tst.l d0
bne 2$
; Gelungen
move.b #CIAICRB_TB,WhichTimer
move.b #CIAICRF_TB,WhichTimerMask
move.l #$bfe601,CiaTimerReg
move.l #$bfef01,CiaControlReg
bra 3$
; Nicht gelungen, dann Parallelport wieder freigeben
2$ move.b #$00,_ciaaddrb ;Port auf Eingabe
move.l _MiscBase,a6
moveq #MR_PARALLELPORT,d0
JSRLIB FreeMiscResource
moveq #2,d0 ;Kein Timer frei
move.l (sp)+,a6
rts
; Alles klar, Timer-Interrupt abschalten und Timer stoppen
3$ move.b WhichTimerMask,d0
JSRLIB AbleICR
move.l CiaControlReg,a0
and.b #$80,(a0)
st.b IECIsOpen
OIECOK moveq #0,d0 ;Alles OK
move.l (sp)+,a6
rts
OIECNoPort moveq #1,d0 ;Parallelport belegt
move.l (sp)+,a6
rts
**
** Benutzung des IEC-Kabels beenden
** Rⁿckgabe: d0=0
**
CloseIEC tst.b IECIsOpen
beq 1$
move.b #$00,_ciaaddrb ;Port auf Eingabe
move.l a6,-(sp) ;Parallelport freigeben
move.l _MiscBase,a6
moveq #MR_PARALLELPORT,d0
JSRLIB FreeMiscResource
move.l CiaControlReg,a0 ;Timer stoppen
and.b #$80,(a0)
move.l _CiaBase,a6
lea TimerInterrupt,a1
move.b WhichTimer,d0
JSRLIB RemICRVector
move.l (sp)+,a6
clr.b IECIsOpen
1$ moveq #0,d0
rts
*
* Locks freigeben
*
FreeLocks move.l