; Open File RSX ; ; Dieses RSX-Modul faengt den BDOS-Aufruf 'Open File' ab. ; Wenn im vorgegebenen FCB '?' auftreten, so wird vor 'Open File' ; die Funktion 'Search First' eingeschoben, damit kein BDOS- ; Error auftritt, und mit dem gefundenen Dateinamen die Open- ; Funktion ausgefuehrt. Wenn nicht, wird der Aufruf direkt an ; das BDOS weitergeleitet. ; TRUE equ 0ffffh FALSE equ NOT TRUE PRINTSTR equ 09 ; Print String Funktion OPENFILE equ 15 ; Open File Funktion SEARCHF equ 17 ; Search First Funktion SCB equ 49 ; Get/Set System Control Block CALLRSX equ 60 ; Call RSX DEBUG equ TRUE ; Debug-Modus liefert mehr Meldungen ; fuer Tests Z80 equ FALSE ; 8080/8085-Code wird generiert ; Beginn RSX-Prefix db 0,0,0,0,0,0 ; Seriennummer jmp START ; Beginn des RSX-Codes NEXT jmp $-$ ; Sprunganweisung PREV dw 0 ; Adresse vorheriges Modul REMOVE db 0ffh ; loesche bei Warmstart NONBANK db 0 ; lade immer RSXNAME db 'OPEN ' ; Name des Modules (8 Stellen) db 0,0,0 ; benutzt von Lader und BDOS ; Beginn RSX-Code START mov a,c ; pruefe BDOS Funktion cpi OPENFILE ; ist dies ein 'Open File' Aufruf ? jz GEFANGEN ; wenn ja, dann tu's ; wenn DEBUG eingeschaltet, dann pruefe zusaetzlich, ob dies ein ; BDOS-Aufruf 'Call RSX' ist. Wenn ja, dann kehre mit Akku =0 ; zum rufenden Programm zurueck, und teile mit, dass das RSX-Modul ; geladen und aktiv ist. if DEBUG cpi CALLRSX ; ist es ein Aufruf fuer diese RSX ? jnz NEXT ; nein, weiter zur naechsten RSX ; oder zum BDOS mov a,d ; liegt ein Testprogramm-Aufruf an ? cpi 0ffh jnz NEXT cmp e ; Register DE = 0ffffh ? jnz NEXT ; nein, gebe Aufruf weiter xra a ; andernfalls setze Register A = 0 ret ; zurueck zum rufenden Programm else jmp NEXT ; zur naechsten RSX oder BDOS wenn ; keine 'Open File-Funktiton' endif GEFANGEN lxi h,0 dad sp ; sichere aktuellen Stackpointer shld USERSTACK lxi sp,RSXSTACK ; richte lokalen Stack ein push b ; sichere Benutzerregister push d ; Ueberpruefe Dateiname auf ' ?' mvi b,11 ; max. Zeichenanzahl im Dateinamen inx d ; setze Zeiger auf 1. Namenszeichen LOOP ldax d cpi '?' ; ist es ein '?' ? jz ERSETZE ; '?' gefunden, fuehre RSX aus inx d ; nein, naechstes Zeichen auch nicht? dcr b ; stelle Zeichenzaehler nach jnz LOOP ; wenn das Programm hier angekommen ist, so befinden sich keine ; '?' im Dateinamen und der BDOS-Aufruf wird unveraendert ; weitergeleitet pop d ; Registerinhalte wiederherstellen pop b lhld USERSTACK sphl ; ebenso den alten Stackpointer jmp NEXT ; und weiter zu BDOS ERSETZE: ; Hier wird die 'Search First'-Funktion eingeleitet, ; der FCB mit dem erstgefundenen Dateinamen gesetzt und ; abschliessend 'Open File' aufgerufen. ; Wenn der 'Search First' ein Fehler meldet, dann meldet ; sich die RSX mit einer einer entsprechenden Fehlermeldung an ; das aufrufende Programm zurueck. if DEBUG lxi d,MELDUNG ; melde dass ein '?' gefunden wurde mvi c,PRINTSTR ; 'Call BDOS' ueber NEXT !! call NEXT endif pop d ; lade Adresse des FCB push d ; und sichern erneut mvi c,SEARCHF ; bereite Funktion vor call NEXT ; und rufe BDOS cpi 0ffh ; nicht gefunden ? jnz GEFUNDEN ; gefunden, so fahre fort ; Hierher kommt das Programm nur, wenn 'Search First' ; nicht erfolgreich war. In diesem Fall unterbleibt der ; Open-Aufruf, da immer noch '?' im Dateinamen stehen, ; und wir kehren mit einer entsprechenden Fehlermeldung ; (Register A bzw. HL) zum rufendden Programm zurueck. pop d ; Registerinhalte wiederherstellen pop b lhld USERSTACK ; ebenso den alten Stackpointer sphl ret ; zurueck zum Programm GEFUNDEN ; 'Search...' war erfolgreich, ersetze alten FCB durch ; den der gefundenen Datei und rufe 'Open File' auf. ; Die 'Search First'-Funktion legt im aktuellen DMA- ; Bereich den Directory-Sektor ab (128 Bytes), in dem ; die gefundene Datei steht und teilt in Reqister A ; mit, welcher dieser 4 Eintraege dazugehoert (0. ..3). ; Der Wert in Register A mit 32 muzltipliziert ist der ; Offset des gueltiqen Eintrags bezogen auf den Anfang ; des Sektors (32 = Laenge eines Directory-Eintrages). add a add a add a add a add a push a ; sichere Offset ; Um den gefundenen Namen laden zu koennen, braucht die ; RSX die aktuelle DMA-Adresse, die im SCB steht. mvi c,SCB ; 'Get/Set SCB'-Funktion lxi d,SCBPB ; SCB Parameter Block Adresse call NEXT ; BDOS Aufruf ; Reqister HL enthaelt nun aktuelle DMA-Adresse pop a ; lade Offsetwert wieder mov c,a mvi b,0 ; setze Offset in Register BC dad b ; HL zeigt nun auf den gefundenen FCB inx h ; setze auf 1.Zeichen des Dateinamens pop d ; lade urspruengliche FCB-Adresse push d inx d ; setze auf 1. Zeichen Ur-Dateiname ; Kopiere den Namen der gefundenen Datei in den FCB des ; aufrufenden Programms (Ur-FCB) if Z80 ; Mit einer Z80-CPU geht das per LDIR anderfalls ; (8080/8085) muss dieser Befehl eliminiert werden. lxi b,11 ; Anzahl Zeichen in Dateiname dw 0b0edh ; Z80 ldir-Befehl else mvi b,11 LDIR mov a,m inx h stax d inx d dcr b jnz LDIR endif ; Der FCB des aufrufenden Programms ist nun bereit ; fuer den 'Open File'-Aufruf. pop d ; Alte Register wiederherstellen pop b ; (Register C enthaelt dann wieder ; die Funktionsnummer fuer Open) lhld USERSTACK sphl ; Alten Stackpointer wiederherstellen jmp NEXT ; Das BDOS wird jetzt ganz normal die Datei oeffnen. SCBPB: ; SCB Parameter Block: Eingerichtet um die aktuelle DMA- ; Adresse zu speichern (Adresse im SCB mit Offset 03ch) OFFSET db 03ch WERT db 0 ; 'Get'-Funktion USERSTACK dw 0 ; Ablage fuer alten Stackpointer ds 10 ; Bereich fuer lokalen RSX-Stack RSXSTACK equ $ ; RSX-Stack Basis ; Wenn DEBUG eingeschaltet ist, so wird folgende Meldung ; generiert if DEBUG MELDUNG db '? im Dateinamen, abgefangen von >OPEN. RSX< ...' db 0dh,0ah,'$' endif end