;      :Program.       NoGuru.obj
;      :Author.        Volker Rudolph
;      :Address.       Medicusstr. 31 / 6750 Kaiserslautern
;      :Phone.         0631/17160
;      :ShortCut.      [vor]
;      :Support.       Bernd Preusing (DisObject)
;      :Version.       1.2
;      :Date.          31.7.1989
;      :Copyright.     PD
;      :Language.      Assembler
;      :Translator.    Asm68k 1.1.0 (PD)
;      :Imports.       Nichts
;      :Contents.      Das Modul NoGuru fängt alle Gurus ab und beendet das
;                      Programm sauber (Arts.Error).
;      :Usage.         Nur importieren.

        include "exec/types.i"
        include "exec/tasks.i"
        include "exec/execbase.i"

_LVOAlert       EQU     -108
_LVOForbid      EQU     -132
_LVOPermit      EQU     -138
_LVORawDoFmt    EQU     -522
_LVOSetFunction EQU     -420

Error           EQU     -90             ; Arts.Error
InitArts        EQU     -6              ; Arts.Init
TermProcedure   EQU     -120            ; Arts.TermProcedure

        SECTION Module,CODE

;--------------------------------------------------------------------------

        dc.l    1       ; Kennung: .obj-File
        dc.w    1       ; mod
        dc.b    'NoGuru'
        ds.b    26
        dc.w    $108A,$000C,$0AE6

; CodeSize
        dc.l    ENDE-Prog
; VarSize
        dc.l    2
; ConstSize
        dc.l    Jumps-Consts
; Jumps
        dc.l    3
; Modules
        dc.l    4

Consts:

Jumps:
        dc.w    $4EF9
        dc.l    RemoveNoGuru-204
        dc.w    $4EF9
        dc.l    InitNoGuru-204
        dc.w    $4EF9
        dc.l    Main-204

ModuleIds:
        dc.w    1       ; mod
        dc.b    'Arts'
        ds.b    28
        dc.w    $0F97,$04DA,$0974

        dc.w    0       ; none
        ds.b    32
        dc.w    $0000,$0000,$0000

        dc.w    0       ; none
        ds.b    32
        dc.w    $0000,$0000,$0000

        dc.w    0       ; none
        ds.b    32
        dc.w    $0000,$0000,$0000

Prog:

dataPtr EQU Prog-20
ArtsBs_ EQU Prog-16

;--------------------------------------------------------------------------

oldAlert:                               ; alte Exec.Alert-Funktion
        ds.l    1
data:   ds.l    1                       ;
guruStr dc.b    'GURU MEDITATION',0     ; Ausgabestring 1
numStr  dc.b    'NUMBER : %08lx',0,0    ; Format-String für RawDoFmt
numBuf  ds.b    20                      ; Ausgabe-Puffer für RawDoFmt

PutChProc:      ; Ausgabe-Prozedur für RawDoFmt
        move.b  d0,(a3)+
        rts

NewAlert:       ; Eigene Alert-Prozedur   (Fehlernummer in d7)
        move.l  4,a6
        lea     numStr(pc),a0           ; Fehlernummer mit RawDoFmt in
        lea     data(pc),a1             ; String umwandeln
        move.l  d7,(a1)
        lea     PutChProc,a2
        lea     numBuf,a3
        jsr     _LVORawDoFmt(a6)
        jsr     _LVOPermit(a6)          ; Multitasking wieder einschalten
        move.l  ArtsBs_(pc),A6          ; Programmabbruch mit Arts.Error
        pea     guruStr(pc)
        pea     numBuf(pc)
        jsr     Error(A6)

LaunchProc:     ; Aufruf bevor der Task Rechenzeit bekommt
        move.l  4,a1                    ; a1: LibraryPtr für SetFunction
        move.w  #_LVOAlert,a0           ; a0: Function-offset für SF.
        lea     NewAlert(pc),a2
        move.l  a2,d0                   ; d0: New-function für SetFuntion
        jsr     _LVOSetFunction(a1)     ; Exec.SetFunction()
        lea     oldAlert(pc),a0         ; Alte Alert-Funktion merken
        move.l  d0,(a0)
        rts

SwitchProc:     ; Aufruf nachdem der Task Rechenzeit verliert
        move.l  4,a1                    ; a1: LibraryPtr für SetFunction
        move.w  #_LVOAlert,a0           ; a0: Function-offset für SF.
        move.l  oldAlert(pc),d0         ; d0: New-function für SetFuntion
        jsr     _LVOSetFunction(a1)     ; Exec.SetFunction()
        rts

InitNoGuru:     ; Installiert eigene Alert-Funktion
        move.l  4,a6
        jsr     _LVOForbid(a6)          ; Forbid()
        move.l  ThisTask(a6),a0         ; a0 := execBase^.ThisTask
        lea     SwitchProc(pc),a1       ; Switch-Prozedur eintragen
        move.l  a1,TC_SWITCH(a0)
        lea     LaunchProc(pc),a1       ; Launch-Prozedur eintragen
        move.l  a1,TC_LAUNCH(a0)
        or.b    #TF_SWITCH!TF_LAUNCH,TC_FLAGS(a0)
                                        ; Setzt Launch- und Switchflag
        bsr.s   LaunchProc
        jsr     _LVOPermit(a6)          ; Permit()
        rts

RemoveNoGuru:   ; Entfernt eigene Alert-Funktion
        move.l  oldAlert(pc),d0         ; Alert-Handler installiert ?
        beq.s   skip                    ; Nein : Ende

        move.l  4,a6                    ; Execbase
        jsr     _LVOForbid(a6)          ; Forbid()
        move.l  ThisTask(a6),a0         ; a0 := execBase^.ThisTask
        clr.l   TC_SWITCH(a0)           ; Switch- und Launchprozedur
        clr.l   TC_LAUNCH(a0)           ; entfernen
        and.b   #~(TF_SWITCH!TF_LAUNCH),TC_FLAGS(a0)
                                        ; Launch- und Switchflag löschen
        bsr.s   SwitchProc              ; Alert-Handler entfernen
        jsr     _LVOPermit(a6)          ; Permit()
        lea     oldAlert(pc),a0         ; oldAlert := NIL;
        clr.l   (a0)
skip:   rts

Main:
        move.l  a4,-(sp)
        move.l  dataPtr(pc),a4
        bset    #0,-2(a4)               ; Ist das Modul schon initialisiert
        bne.s   noInit                  ; worden ? Wenn ja: überspringen

        lea     oldAlert(pc),a0         ; oldAlert := NIL
        clr.l   (a0)
        move.l  ArtsBs_(pc),A6          ; Arts initialisieren
        jsr     InitArts(A6)
        move.l  ArtsBs_(pc),A6          ; Arts.TermProcedure(RemoveNoGuru);
        pea     RemoveNoGuru(pc)
        jsr     TermProcedure(A6)
        bsr     InitNoGuru              ; NoGuru initialisieren

noInit:
        move.l  (sp)+,A4
        rts
ENDE:
        END
