' -------------------------------------------------------------------------- ' Beispielprogramm zum Shellaufruf in Omikron Basic ' -Start PRINT "Beispielprogramm zum Shellaufruf in Omikron Basic" INPUT "Gewuensches Kommando (Programmstop mit ENDE) ";Shell_Cmd$ IF Shell_Cmd$="ENDE" OR Shell_Cmd$="Ende" OR Shell_Cmd$="ende" THEN CLS : END CLS GOSUB System_Call PRINT "Rueckgabe der Shell: ";S_Exitcode GOTO Start END ' ' ' ' ########################################################################## ' SYSTEM_CALL ' Eingabe : Shell_cmd$ enthaelt eine Kommandozeile fuer eine Shell ' Rueckgabe : S_Exitcode enthaelt entweder -999 falls keine Shell vorhanden ' oder den Rueckgabewert des Shellaufrufs ' ' Verwendete Variablen ' S_Init --- internes Flag 0=Nicht initialisiert 1=Initialisiert ' Shelltyp --- Art der Shell, wird selbststaendig initialisiert ' 0 = Keine Shell vorhanden ' 1 = Unbekannte Shell vorhanden ' 2 = GULAM vorhanden ' 3 = MASTER >= 5.0 vorhanden ' S_Adr --- interne Adresse fuer Uebergabewerte an die Unterroutine ' S_Ptr --- interne Adresse fuer den Kommandostring ' S_I --- interner Allzweckzaehler ' ' Benutzte Labels ' Systemcall - die Routine fuer den Benutzer ' Exit_Systemcall - internes Label ' Init_System_Call - interne Installationsroutine ' Mc68000code - interne DATA Werte fuer das Maschinenunterprogramm ' Install_Systemcall - internes Label ' Exit_Init - internes Label ' ########################################################################## ' -System_Call S_Exitcode=-999' * Defaultwert falls keine Shell da ist IF S_Init=0 THEN GOSUB Init_System_Call' * Installation einer Unterroutine IF Shelltyp<2 THEN GOTO Exit_Systemcall' * unbekannte oder keine Shell ' else S_Ptr= MEMORY(Shell_Cmd$)' * einen C-String mit Nullende bauen ' ' jetzt pruefen, ob eine interaktive Shell erwuenscht ist ' fuer MASTER wird "-i" uebergeben, der fuer GULAM ' in einem Leerstring "" umgesetzt werden muss IF Shelltyp=2 AND Shell_Cmd$="-i" THEN S_Ptr= MEMORY("") LPOKE S_Adr,S_Ptr' * Stringadresse in die Unterroutine CALL S_Subroutine' * schreiben und diese aufrufen S_Exitcode= WPEEK(S_Adr)' * den Rueckgabewert jetzt auslesen -Exit_Systemcall RETURN ' ' ' -Init_System_Call IF S_Init=1 THEN GOTO Exit_Init' * nicht doppelt installieren Shell_P= LPEEK($4F6)' * Systemvariable auslesen IF Shell_P=0 THEN Shelltyp=0: GOTO Exit_Init' * Nullpointer -> keine Shell ' else Shelltyp=1' * default unbekannte Shell ' ' GULAM magicnumber pruefen IF LPEEK(Shell_P-10)=$420135 THEN Shelltyp=2: GOTO Install_Systemcall ' else ' MASTER magicnumber fuer >=5.4 pruefen IF LPEEK(Shell_P-8)=$4D415354 THEN Shelltyp=3: GOTO Install_Systemcall ' MASTER magicnumber fuer 5.0 pruefen, da mit &CDCEC5D2 Probleme mit ' dem 8. Bit auftauchen, wird dieses ausmaskiert IF NOT(( WPEEK(Shell_P-4) AND $7FFF)=$4DCE) THEN GOTO Exit_Init IF NOT(( WPEEK(Shell_P-2) AND $7FFF)=$45D2) THEN GOTO Exit_Init ' else Shelltyp=3' * MASTER gefunden -Install_Systemcall S_Adr= MEMORY(36)' * Platz fuer Unterprogramm RESTORE Mc68000code' * beschaffen und das pc- FOR S_I=S_Adr TO S_Adr+34 STEP 2' * relative Programm einbauen READ A: WPOKE S_I,A NEXT S_I -Mc68000code DATA $0,$0,$0,$0,$2F08,$41FA,$FFF4,$2F10,$41FA,$FFF2,$2050,$4E90,$588F, $41FA,$FFE4,$3080,$205F,$4E75 S_Subroutine=S_Adr+8' * und den Zeiger auf die LPOKE S_Adr+4,Shell_P' * Shell einbauen S_Init=1' * Initialisierung fertig -Exit_Init RETURN ' ' Assemblertext fuer die Maschinenunterroutine ' ' cmd_line: .DC.l 0 ' shell_p: .DC.l 0 ' move.l a0,-(sp) ; register a0 retten ' lea.l cmd_line(pc),a0 ' move.l (a0),-(sp) ; zeiger auf die kommandozeile uebergeben ' lea.l shell_p(pc),a0 ' movea.l (a0),a0 ; den zeiger auf die shell holen ' jsr (a0) ; und die shell anspringen ' addq.l #4,sp ' lea.l cmd_line(pc),a0 ' move.w d0,(a0) ; den rueckgabewert aus d0 holen ' movea.l (sp)+,a0 ; und a0 restaurieren ' rts ' ' -------------------------------------------------------------------------- ' ' Anmerkung: Werden ueber die Shell weitere Programme gestartet, kann es ' leicht zu Speicherplatzmangel kommen. Unter MASTER kann dieses ' Problem umgangen werden, wenn vor Start des Interpreters mit ' SHRINK der Speicher zunaechst verkleinert wird und dann im ' Interpreter via Shellaufruf mit FREE wieder freigegeben wird. ' Externe Programme koennen nun diesen Platz komplett nutzen. ' ' --------------------------------------------------------------------------