(* Atari monitor   12.06.86  Th.Tempelmann V#0588  *)

MODULE TEMPLMON;
(*$C-,N+,L-,R-,Q+,V+,P-*)

FROM SYSTEM IMPORT ASSEMBLER;

CONST
  German = FALSE; English = TRUE;
  StandAlone = TRUE;
  ADC = FALSE; (* erw. Tastatur-Routinen v. Andi Cambeis *)
  ExtendedKeys = TRUE; (* erw. Tastenabfrage? *)
  AltHelp = FALSE; (* ALT/HELP-Aufruf? *)

(*----------------------------------------------------------------------------
12.06.86  1.0  šbernahme des Gepardmonitors V2.9; Alle Zugriffe relativ
15.06.86  1.0  erste Tests auf Atari; Code an HHH
19.06.86  1.1  Trace-Abbruch mit ALT/HELP, Monitor-Screen
20.06.86  1.1  Test auf šberlauf d. Eing.zeile; 8*16-DispChar linear;
               Backspace impl.; Key-Brk testet PC, ob im Mon.;
               Code an OJO
21.06.86  1.2  Traceroutine: TrcStat in D7.B;
22.06.86  1.2  Deutsche Texte, Vorbereitung als public domain-Version
23.06.86  1.2  ConIn/Stat: Trap#13 wird neuer Hilfs-Speicher zugewiesen;
               EyRTU/EyRTN ok.
24.06.86  1.2  User-Trace verbessert
25.06.86  1.2  Engl. Version fertig, Deutsche und Engl. als Public domain an
               OJO und HHH
29.07.86  1.3  Save impl., 2 Fehler in Dism20 beh., bei NMI wird Int-maske
               zur�ck auf 3 gesetzt, Protokoll-Funktion impl.;
               Amerikanischen Text verbessert (Dank an Niels Jaeckel !)
20.09.86  1.4  Zeile wird bei "R:", "C" und "V" nicht mehr gel”scht; "M", ":",
               "C" und "V" arbeiten byteweise, Texte erweitert am Ende;
               Offset-Var geht mit z.B."~A0"; "0", "1", "D", "S", "F" und "B"
               bei TrcCtrl; ShortBPs mit "," bei "G"-Funktion; Statt '~' jetzt
               'R'; GetByteX; Errortest bei BP setzen; 'O' und "'" auf unger.
               Adr.; Farbausgabe (80 Zeichen); BP-setzen nur auf gerage Adr.;
               Tracing beschleunigt; BPs werden bei 'Q' gel”scht; "RS" u. "RR";
               BP #1-7 gehen auch; "VI";
               Fertigstellung 14.10.86.
13.01.87  1.5  Protocol: Keine Ctrl-Zeichen (aužer CR,LF,FF) an Drucker, LF
               wird trotz Screen-Unterdr�ckung an Drucker gesendet. Load neu,
               bei S/L Angabe der rel. Fileadr. m”glich, wenn keine Adr. bei L,
               dann wird Speicher angefordert. BP-Anzeige: Nur benutzte BPs.
               F erkennt wieder, daž nicht 2 Adr. anggeben wurden. GetAdr l„žt
               Expr. mit '+' und '-' zu. Dism2: BTST # richtiger. Bei vielen
               GetEA-Aufrufen ungerade Adr. erlaubt.
14.02.87  1.6  HKom: kein CAPS mehr; RgPC: MSByte wird gel”scht, dadurch Fehler
               beseitigt, daž BPs zeitweise (im ROM) nicht erkannt werden.
23.06.87  1.7  "VI" setzt BEV/AEV richtig; Protokoll unterdr�ckt endlich Ctrl-
               Zeichen richtig; von "GS" und "R" ohne Supervisor-State wird
               wieder korrekt zur�ckgekehrt.
23.06.87  1.8  Keine Farbschatten mehr.
23.08.87  1.9  IR-Freigabe, wenn Tastatur gesperrt
18.09.87  1.10 SHIFT-Abfrage bei ALT/HELP
09.11.87  1.11 ALT/HELP ohne Shift, Harcopy mit.
06.02.88  1.12 Kein Install bei zweitem Aufruf, meine Adr. neu, Tastatur-
               abfrage bei IR-Sperrung verbessert, nur noch TRAP #6 umgeleitet,
               Msg bei Installation, Anleitung (dtsch) raus.
08.03.88       Anleitung (engl) raus, conditional Compiling f�r Sprache.
22.12.88  1.13 ADC: TEMPLMON auf ATARI-Megamax-Modula 2 angepasst;
               Neue Tastatur-Abfrage
02.01.89       XBRA-Kennungen; Bei Quit wird Mon-SP verwendet; Kein H„nger mehr
               bei Bus/Addr-Error w„hrend Single Step; Patch-Vars f�r Cursor-
               blinken und Stacksize; Direktaufruf �ber IRQ#1 ($64).
14.01.89  1.14 VI zeigt ge„nderte Vektoren an.
01.04.89  1.15 Trace Bit nicht mehr an bei Q (in 1.14 drin gewesen).
16.06.89  1.16 "Q" korrigiert (SSP und USP durften sich nicht �berlagern)
14.07.89  1.17 Beim Start werden wieder alle Traps abgefangen, bei VI nur
               Trap 6; MSBytes von geretteten Bus-/Addr-Error-Vektoren werden
               nicht mehr auf 2 bzw. 3 gesetzt (in ResetMon).
26.04.90       68020-Anpassung;
               EyKBD: Bei ALT/HELP wird die Alt-Taste ausdr�cklich abgefragt,
               damit kein TMon-Aufruf bei Hardcopy �ber Men� passiert;
               Norm/MonScrn: $FF8260-Reg wird nun (hoffentlich) TT-kompatibel
               angesprochen; Format Error $38 f. 68020 abgefangen.
08.09.90 1.17c engl. Version zum Testen an GEnie
09.09.90 1.17d VBL-Routine zum Tastenabfrage raus, weil Probleme mit TT;
               Stattdessen direkter Abfang auf IR6-Vektor.
               IR-Maske kann in PatchVars bestimmt werden.
10.09.90 1.17e Warteschleife bei M & I, wenn 68020; $FF8260 mit 7 maskiert.
04.10.90 1.19O Editierbare Kommandozeile, History Funktion, OverScan Anpassung,
               Befehle mw,ml,:w,:l,p Adressierung, Abbruch wenn bei S Befehl
               zweite Adrežangabe fehlt, Abbruch wenn bei Installation Shift
               Taste gedr�ckt.
11.10.90 1.19P HyperScreen video_modus gesetzt.
11.10.90 1.19Q TT Shift Mode Register richtig ausmaskiert. STE und TT wird anhand
               von CookieJar getestet, nicht mehr nach Prozessor und Buserror bei
               Zugriff auf STE Register.
12.10.90 1.19R Malloc f�r Bildschirm :=> l„uft jetzt auch mit TT Fast Ram
22.10.90 1.19S Korrektur von Bildschirmspeichergr”že & ComdQ, Korrektur der
               OverScan-Umschaltroutinen.
12.11.90 1.20 TT Texte f. nicht-Installation korrigiert, Privilegs-Exc wird
               nun abh„ngig vom TT installiert.
               Johannes! Merke Dir: Nie wieder TABs in die Texte, wenn Du
               sie mit schickst! Aužerdem: Verwende MOVEQ statt MOVE, wenn
               Du Werte zw. 0 und 128 in ein Reg laden willst! Statt CMP #0
               verwende TST, statt ADDA.L/CMPA.L mit Werten kleiner als
               32768 verwende ".W"! Verwende BCS/BCS statt BLT/BGE!
----------------------------------------------------------------------------*)
(* Traceroutine: wenn Abbruch, wird z.Zt. D7 nicht nach TrcStat zur�ck-
   gespeichert ! *)
(* Hinter TrcCtC2 wird SR getestet, aber ist es denn immer schon richtig ge-
   setzt, oder wird es bei CGo nochmal vielleicht ver„ndert ??? *)


(* Registerverwendung innerhalb der Prozedur MONITOR:
   
   D0: Enthaelt meist das letzte geholte Zeichen aus dem Eingabepuffer.
   
   D3: COU: enth„lt Registerauswahl, die in Eingabepuffer steht. Bit 31 gibt
         dabei an, daž das SR mit 'F..' gew„hlt wurde.
   
   A5: Enthaelt ^ auf Ende der Zeichen im Eingabepuffer.
   
   A6: Enthaelt ^ in Eingabepuffer auf letztes geholtes Zeichen.
   
   D7: in den Traceroutinen enth„lt es die Variable TrcStat,
       sonst nur Flags ( ganzes Longword ); Wirkung bei gesetzten Flags:
       Bit 0: Bei PRTREG (Ausgabe der Register) sollen nur die Registernamen
              ausgegeben werden.
       Bit 1: Wird von GETAE (holen von Anf./End-Adr.) gesetzt, wenn keine
              Endadr., sondern eine Zeilenanzahl gewaehlt wurde.
       Bit 2: Bei GETAE (s.o.):
                In A2 steht die Anf.-Adr.
              Bei PRTREG (gibt Reg. aus, Nummer (TNr..) in D2):
                SR als Flags anzeigen
              Bei BERREGNR (bestimmt ausgewaehltes Register z.B. 'A2'
              und schreibt Tabellennummer nach D2 ):
                Es wurde ein Flag (mit z.B. 'FC') gewaehlt und die
                entsprechende Flagnummer steht in D2.
       Bit 3: Bei GETAE (s.o.):
                In A3 steht die End-Adr.
              Bei BERREGNR:
                Es wurde 'F' als Register statt 'SR' eingegeben.
       Bit 4: Bei BERREGNR (s.o.):
                Auf Zuweisung der Register abfragen und evtl. zuweisen.
              Bei GETFNDBF (legt Suchstring byteweise in FindBuf ab):
                wird nur intern benutzt.
       Bit 5: Nicht benutzt.
       Bit 6: Nicht benutzt.
       Bit 7: Bei ComdG ( 'G'-Kommando ):
                Nur interne Benutzung.
       Bit 8: Bei PRTREG/PRTSRBIN (SR anzeigen):
                Nur T-Flag anzeigen.
       Bit 9: Bei CRU (Reg-Ausgabe - Upro ):
                Nur interne Benutzung.
       Bit 10:Bei PRTREG/CRU:
                Nur interne Benutzung (ob tabellarische Ausgabe von D0-A7).
       Bit 11:Bei Aufruf von PRTCRLF soll kein LF ausgeben werden.
       Bit 12:Bei Aufruf von GETADRG / GETAE soll nicht auf gerade
                Zahlen gerundet werden.
       Bit 13:PRT: n„chstes Ascii-Zeichen soll nicht als Controlzeichen
                ausgegeben werden
       Bit 14:Nicht benutzt.
       Bit 15:Wird von GETNGRKL / GETLGRKL gesetzt, wenn
                letztes geholtes Zeichen ein CR ist.
       Bit 16
          -31:Nicht benutzt.   *)


(* globale Variablen *)
(* ***************** *)

VAR
         SvA4: LONGCARD;    (* wird bei Entries als Zw.-Speicher benutzt *)
         MonActive: CARDINAL;  (* nur 1.Byte *)
         Kbdv_base: LONGCARD;
         StkFrm   : CARDINAL; (* Stackframe: 0 bei 68000, 2 ab 68010 *)

(*$ ? ExtendedKeys:
         CallFlag     : CARDINAL;
         LockFlag     : CARDINAL;
         IorecPointer : LONGCARD;
*)


PROCEDURE MONITOR;

(* LAGE ALLER WICHTIGEN EXCEPTION-VEKTOREN IM SYSTEMRAM *)

CONST    magic    = 'TMon';

         BUSERRV  = $08L;
         ADRERRV  = $0CL;
         ILLCMDV  = $10L;
         DIVZV    = $14L;
         CHKV     = $18L;
         TRAPVV   = $1CL;
         PRIVV    = $20L;
         TRACEV   = $24L;
         EM1010V  = $28L;
         EM1111V  = $2CL;
         FRMERRV  = $38L;
         ILLIRQV  = $60L;
         IRQ1V    = $64L; (* wird f. Mon-Direkteinsprung benutzt *)
         IRQ2V    = $68L;
         IRQ3V    = $6CL;
         IRQ4V    = $70L;
         IRQ5V    = $74L;
         IRQ6V    = $78L;
         IRQ7V    = $7CL;
         Trap0V   = $80L;
         Trap3V   = $8CL;
         Trap6V   = $98L;

         MidiKeyV = $118L; (* ADC: Keyboard/ Midi IRQ-Vector *)
         USRBPV   = $41CL;

         etv_critic = $404L;
         end_os     = $4FAL;

CONST    codelen  = 12;
         datalen  = 20;
         bsslen   = 28;

         PROMPT   = '!';
         ASCPRMPT = $27;
         JOKER    = '?';
         OFFSCHAR = 'O';
         ZEILLEN  = 80; (* LŽNGE EINER BILDSCHIRMZEILE *)
         HDUMPANZ = 16; (* ANZAHL Bytes BEI HEX-DUMP *)
         ADUMPANZ = 64; (* ANZAHL BYTES BEI ASCII-DUMP *)
         ASCDUMPX = 0;  (* ANZAHL SPACES NACH HEX-DUMP BIS ASCII-ANZEIGE *)

         CARRY    = 1;
         ZERO     = 4;
         NEGZERO  = -4;
         EXTEND   = 16;

         BSKey    = 8;    (* Tastencodes f�r editierbare Kommandozeile *)
         DelKey   = 127;
         CurRKey  = $15;
         CurLKey  = $14;
         InsKey   = $16;
         HomeKey  = $10;
         EndKey   = $11;
         WordRKey = $13;
         WordLKey = $12;
         WordHome = $17;
         WordEnd  = $18;
         ESCKey   = 27;

         CR       = $D;
         LF       = $A;
         FF       = $C;
         BS       = $8;
         ClEol    = $1;
         ClEoS    = $2;
         Con      = $4;
         Coff     = $5;
         SPC      = ' ';
         relFchr  = '@';

         BEFJMP   = $4EF9;
         BEFBRK   = $4AFC;
         BEFRTS   = $4E75;
         BEFRTE   = $4E73;
         BEFRTR   = $4E77;

  (* Tabellennummern der Reg. fuer Anzeige, es reicht aber nicht,
     nur diese zu aendern. (Siehe Kommentare - nach den Variablen suchen! ) *)
         TNRSR    = 0;
         TNRD0    = 1;
         TNRA0    = 9;
         TNRA7    = 16;
         TNRPC    = 17;
         TNRUSP   = 18;
         TNRSSP   = 19;
         TNRBER   = 20;
         TNRAER   = 21;
         TNrLast  = 21;

(*$ ? ExtendedKeys:
CONST     iorec           = $e;     (* XBios Funktionen *)
          kbdvbase        = 34;
          xbios           = 14;
          memvalid        = $420;
          resvalid        = $426;
          memval2         = $43a;
          _sysbase        = $4f2;
          memval3         = $51a;
*)

VAR
(* Farbpaletten : *)
      farbe                     : ARRAY [0..3] OF CARDINAL;

      video_plane               : CARDINAL;
      video_line_bytes          : CARDINAL;
      video_memory              : LONGCARD;
      tmon_offset               : LONGCARD;

      TT_Shift_Mode             : CARDINAL; (* Shift Modus Register des TT *)
      entry_video_modus         : CARDINAL; (* OverScanModus beim Aufruf von TempleMon? *)
      video_modus               : CARDINAL; (* OverScan oder Normal nutzen? *)
      autoswitch                : CARDINAL; (* AutoSwitch Hardware ? *)


         old_sync  : CARDINAL;

         EditModus : CARDINAL;

         KEYBUF  : ARRAY [0..ZEILLEN] OF CHAR;

         REGBEG  : CARDINAL; (* Leerwort fuer Ausgleich des Wortes f. d. SR *)

         (* Achtung : Reihenfolge nicht vertauschen ! *)
         RgSR    : ARRAY [1..1] OF CARDINAL;
         RgD0    : ARRAY [0..11] OF LONGCARD;
         RgA4    : ARRAY [4..5] OF LONGCARD;
         RgA6    : ARRAY [6..6] OF LONGCARD;
         RgA7    : ARRAY [7..7] OF LONGCARD; (* RgA7 unbenutzt, dummy f. SSP/USP *)
         RgPC    : ARRAY [1..1] OF LONGCARD;
         RgUSP   : ARRAY [1..1] OF LONGCARD;
         RgSSP   : ARRAY [1..1] OF LONGCARD;
         RgBEV   : ARRAY [1..1] OF LONGCARD;
         RgAEV   : ARRAY [1..1] OF LONGCARD;
         RgSF    : CARDINAL;

         LBLBEG  : CARDINAL;                 (* Dummy - Wort, nicht loeschen ! *)

         (* Achtung : Reihenfolge nicht vertauschen ! *)
         TRCSTAT : ARRAY [1..1] OF CARDINAL;
         TRCSVSP : ARRAY [1..1] OF LONGCARD;

        RgSFC,RgDFC,RgCACR,RgVBR,RgCAAR,RgMSP,RgISP : ARRAY [1..1] OF LONGCARD;

(*         MonActive : CARDINAL; *) (* nur 1.Byte *)

CONST    BPanz = 8;

VAR      (* Achtung : Reihenfolge nicht vertauschen ! *)
         BP      : ARRAY [0..7] OF LONGCARD;
         BPC     : ARRAY [0..0] OF CARDINAL;
         BPCA    : ARRAY [0..0] OF CARDINAL;
         BPDUMMY : ARRAY [1..7] OF LONGCARD;
         BPSV    : ARRAY [0..7] OF CARDINAL;
         BPSTAT  : ARRAY [0..0] OF CARDINAL;
         BPset   : CARDINAL;
         BPquest : CARDINAL;
         
CONST    ShBPanz = 9;
         
VAR      ShBPcnt : CARDINAL;
         ShBP    : ARRAY [1..ShBPanz] OF LONGCARD;
         ShBPsv  : ARRAY [1..ShBPanz] OF CARDINAL;
         ShBPFlg, (* Byte *)
         ShBPStat: CARDINAL;


         REGWAHL : LONGCARD;   (* Bit 31 : SR als Flags anzeigen (nur g�ltig,*)
                               (*  wenn auch SR-Bit gesetzt) *)

         RegSave : ARRAY [0..19] OF LONGCARD;

         (* Achtung : Reihenfolge nicht vertauschen ! *)
         ADOFFSET : LONGCARD;
         LASTMA   : LONGCARD;
         LASTME   : LONGCARD;
         LASTDA   : LONGCARD;
         LASTDE   : LONGCARD;
         LASTIA   : LONGCARD;
         LASTIE   : LONGCARD;
         Hilf1L   : LONGCARD;
         
         RWhandle,
         Prhandle : CARDINAL;
         
         FileStart,
         FileLen,
         MemLen   : LONGCARD;
         MemAdr   : LONGCARD;  (* wenn # 0, dann Block angefordert *)
         OverWrite: CARDINAL; (* oberes Byte, bool *)

         ValExp   : CARDINAL; (* oberes Byte, bool *)

         isSTE,               (* zus„tzliche Videoregister bei STE *)
         isTT,                (* neue Grafik bei TT *)
         is20,                (* wenn 68020 oder h”her *)
         StkFrTrc: CARDINAL;  (* Stackframe f. Trace: 6 ab 68010 *)

         origRes: CARDINAL;
         physAdr, logAdr: LONGCARD;
         
         NoScrDisp,
         ch       : CARDINAL;

         Rows,
         Lines,
         CharHeight,
         CursorX,
         CursorY     : CARDINAL;
         CursorState : BOOLEAN;
         CursorCnt   : LONGCARD;

         LBLEND  : CARDINAL;                 (* Dummy - Wort *)
         
         SUPSR   : CARDINAL;
         ERRADR  : LONGCARD;
         ERRBEF  : LONGCARD;

         ExcNo   : CARDINAL;
         ENTRYMSG: LONGCARD;
         EntryNr : CARDINAL;
         ENTRYMOD: CARDINAL; (* NUR 1.BYTE; BITS: 0:BUS-,ADRERR, 1:EntryNr. ausgeben *)

         FindBuf : ARRAY [0..32] OF CHAR;

         MonStackHi: LONGCARD;

LastLocalVar : CARDINAL;    (* muss immer am Ende der Vars stehen ! *)

BEGIN
ASSEMBLER
StartOfMon
          BRA.L   INITGMON

          ; hier beginnen die Patch-Variablen
          ASC     'TemplemonVar'
StackSize DC.L    512           ; Default-Stackgr”že
BlinkRate DC.L    $2000         ; Wenn Null, dann kein Blinken
IRMask    DC.W    $0500         ; IR-Maske im Monitor
DumpDelay DC.L    1234          ; Wartezeit bei 68020 bei Cmds M, I
ext_flag          DC.W      0   ; 0 = gucken ob neue Tastatur Routine in VBL
                                ; Queue pažt, sonst gleich Hardcopy Vektor
                                ; verbiegen (Boole'scher Wert!)
tmon_shiftkeys    DC.B      4   ; Status der Umschalttasten f�r Tastaturaufruf
tmon_scancode     DC.B      $62 ; Scancode f�r Tastaturaufruf
reset_kalt_shiftkeys  DC.B  $d  ; Status der Umschaltt. f�r Kaltstart
reset_warm_shiftkeys  DC.B  $c  ; Status der Umschaltt. f�r Warmstart
reset_scancode    DC.B      $53 ; Scancode f�r Kalt und Warmstart
                  SYNC
m_VideoBytes      DC.W    100   ; Anzahl der Bytes pro Zeile monochrom
m_VideoMemory     DC.L  50000   ; Gr”že des Bildschirms monochrom
tmon_offset_mon   DC.L   5010   ; BildschirmOffset Monochrom falls Hyperscreen;
                                ; wird in Bytes angegeben und zum Bildschirm-
                                ; offset addiert.
c_VideoBytes      DC.W    236   ; Anzahl der Bytes pro Zeile Farbe
c_VideoMemory     DC.L  73160   ; Gr”že des Bildschirms Farbe
tmon_offset_col   DC.L  13018   ; dito wie tmon_offset_mon nur f�r Color-
                                ; betrieb
sync_shiftkeys    DC.B      $c  ; Status der Umschaltt. f�r Resynchronisation
sync_scancode     DC.B      $66 ; Scancode f�r Resync.
                  SYNC
sync_time_mono    DC.W      $2000  ; Resynchronisationszeit in 10*Takt f�r
                                   ; Monochrom Aufl”sung
sync_time_mid50   DC.W      $3000  ; Resynchronisationszeit f�r Mid 50 Hertz
sync_time_mid60   DC.W      $2500  ; Resynchronisationszeit f�r Mid 60 Hertz
sync_time_low50   DC.W      $3000  ; Resynchronisationszeit f�r Low 50 Hertz
sync_time_low60   DC.W      $2500  ; Resynchronisationszeit f�r Low 60 Hertz
video_sync_flag   DC.B      0   ; <> 0 Video Sync Register mit video_sync_byte
                                ; f�llen
video_sync_byte   DC.B      2   ; Inhalt des Video Sync Registers, wenn nicht
                                ; der urspr�ngliche Inhalt gesetzt werden soll
video_sync_intern DC.B      $FF ; zum Testen auf interne Synchronisation
                                ; schalten. 0 = externe Sync.
abort_key_mask    DC.B      1   ; Rechte Shift Taste Installationsabbruch
edit_lines        DC.B      10  ; Anzahl der zu puffernden Eingabezeilen
                  SYNC
mono_0            DC.W      0   ; Inhalt des Farbregisters 0 bei Mono
tt_mono_0         DC.W      0
tt_mono_1         DC.W      $FFFF
color_0           DC.W      $0000
color_1           DC.W      $FFFF
color_2           DC.W      $FFFF
color_3           DC.W      $FFFF
edit_modus        DC.B      $FF  ; $FF = Insert Modus, 0 = Overwrite Modus
                                 ; (Ins toggelt Mode)
                                 ; $7F = Leerzeicheneinf�gemodus
                                 ; (generell Overwrite Modus, Ins f�gt
                                 ;  Leerzeichen ein)
                  SYNC
edit_minimum      DC.B      3    ; Mindestl„nge einer Eingabezeile, die im
                                 ; Historypuffer gespeichert wird.
sync_on           DC.B      78   ; interne Synchronisation
sync_off          DC.B      74   ; externe Synchronisation
                  SYNC


(*$ ? German:

!PressKeyMsg  ACZ  ' --- SPACE-Taste druecken --- '

!CmdCmt
ACZ '                     TEMPLEMON / Version 1.20 / 12.11.90'
ACZ '                     -----------------------------------'
ACZ '          Copyright (C) [1986..1990], Thomas Tempelmann, Johannes Hill'
ASC '       Thomas Tempelmann, Nordendstr. 64, 8000 M' DC.B 129 ACZ 'nchen 40, West Germany'
ACZ '       Johannes Hill,     Alicenstr. 30,  6100 Darmstadt 1, West Germany'
ACZ '-------------------------------------------------------------------------------'
ACZ 'Die Versionen 1.x dieses Monitors sind frei kopierbar. Allerdings nur in der'
ACZ 'Originalversion, das schliesst ein, dass dieser Text incl. der Urheberrechts-'
ACZ 'angabe nicht geloescht werden darf und dass immer der ganze Ordner, in dem'
ACZ 'sich dieser Monitor befindet, kopiert wird (mit den Dateien LIESMICH, TRACE.M,'
ACZ 'TEMPLMON.PRG) !'
ACZ ' '
ACZ 'Die Hyperscreenkorrektur vom 30.01.91 ist implementiert.'
ACZ ' '
ACZ 'TEMPLEMON wurde mit Megamax Modula-2 entwickelt.'
ACZ ' '
(*
ACZ 'Eine ausfuehrlichere Anleitung mit hilfreichen Tips zur Fehlersuche erhalten'
ACZ 'Sie fuer nur noch DM 20.-! Ausserdem koennen Sie uns dadurch gleich Ihre Aner-'
ACZ 'kennung zu unserem Programm bekunden.'
ACZ ' '
*)
ACZ '    Mit freundlichen Gruessen       Thomas Tempelmann, Johannes Hill'
DC.B 0,0
*)

(*$ ? English:

!PressKeyMsg  ACZ  ' --- press SPACE --- '

!CmdCmt
ACZ ' '
ACZ '------------------------------ TEMPLEMON 1.20 ------------------- 11/12/90 ----'
ACZ ' '
ACZ '                   Copyright (C) 1986, Thomas Tempelmann'
ASC '  Thomas Tempelmann, Nordendstr. 64, D-8000 M' DC.B 129 ACZ 'nchen 40, West Germany'
ACZ '             BIX: tempel / CIS: 72377,351 / GEnie: T.TEMPELMANN'
ACZ '      Johannes Hill, Alicenstr. 30,  D-6100 Darmstadt 1, West Germany'
ACZ ' '
ACZ '-------------------------------------------------------------------------------'
ACZ 'The versions 1.xx of TEMPLEMON may be considered Freeware and can be freely'
ACZ 'copied under the following condition:'
ACZ 'TEMPLMON.PRG must be in a folder named TEMPLMON when a copy is made for'
ACZ 'others. The files READ.ME and INSTRUCT.TXT must be included in the folder.'
ACZ '-------------------------------------------------------------------------------'
ACZ ' '
ACZ 'From version 1.20 on, TEMPLEMON may also be used on the Atari STE & TT.'
ACZ 'Read the file INSTRUCT.TXT for explanation of the commands.'
ACZ ' '
ACZ 'The hyperscreencorrection from 01/30/91 is implemented.'
ACZ ' '
ACZ 'TEMPLEMON has been developed with Megamax Modula-2.'
ACZ ' '
ACZ 'We hope that you will find TEMPLEMON useful and that your bug-swatting problems'
ACZ 'are eased by this monitor.'
ACZ ' '
ACZ 'Thomas Tempelmann, Johannes Hill'
DC.B 0,0
*)

;*** MESSAGES

(*$ ? German:
!UsrBPMsg ACZ  'Stop durch User-Trace Routine'
!ExcMsg   ACZ  'Exception #'
!Exc2Msg  ACZ  ' : '
!ERRMSG   ACZ  'Fehler: '
LOADMSG   DC.B CR,LF
          ACZ  'Lade ab '
SAVEMSG   DC.B CR,LF
          ACZ  'Speichere ab '
!ENDMSG   ACZ  ', erste unbenutzte Adresse: '
!RTNMSG   ACZ  'R�ckkehr von GS'
!FrmErMsg ACZ  'Format Error'
!ILLMSG   ACZ  'Illegale Instruktion'
!ILLIMSG  ACZ  'Illegaler Interrupt'
!IRQMSG   ACZ  'Interrupt #'
!TRAPMSG  ACZ  'Trap #'
!TRPVMSG  ACZ  'TRAPV - Instruktion'
!CHKMSG   ACZ  'CHK - Instruktion'
!BRKMSG   ACZ  'BREAK - Instruktion'
!BPMSG    ACZ  'Stop durch Breakpoint'
!DIVMSG   ACZ  'Division durch Null'
!PRIVMSG  ACZ  'Privilegs-Verletzung'
!KBDEMSG  ACZ  'Unterbrechung durch Tastatur'
!DirCMSG  ACZ  'Direktaufruf (JSR)'
!BPNMSG   ACZ  'Stop durch Breakpoint #'
!TRMMSG   ACZ  'Tracemodus '
NAKTMSG   ACZ  'nicht aktiv'
AKTMSG    ACZ  'aktiv'
!CFLMSG   ACZ  ' C:'
!RMDMSG   ACZ  ' R:'
!BEMSG    ACZ  'BUS ERROR bei '
!AEMSG    ACZ  'ADDRESS ERROR bei '
!SRMSG    ACZ  ' - SR:'
!SSRMSG   ACZ  ' / Super-SR:'
!EBFMSG   ACZ  ' / Instruktion:'
ProtMsg   DC.B    CR,LF
          ACZ     'Protokolldatei ge'
OpMsg     ACZ     'oeffnet'
ClosMsg   ACZ     'schlossen'
IOResMsg  DC.B    CR,LF
          ACZ     'TOS-Error #'
ShBPMsg   ACZ     'Breakpoint gesetzt auf '
SkipMsg   ACZ     'Nicht ausgefuehrt.'
BPErrMsg  ACZ     'Breakpoint konnte nicht gesetzt werden auf '
noBPsMsg  DC.B    CR
          ACZ     'Keine Breakpoints gesetzt'
noMemMsg  DC.B    CR,LF
          ACZ     'Kein gen�gend grosser Speicherbereich frei'
OkMsg     DC.B    CR,LF
          ACZ     'OK.'
notAllocMsg DC.B  CR,LF
          ACZ     'Bereich war unbelegt'
noInstallMsg DC.B CR,LF
          ASC     'TEMPLEMON ist bereits installiert.'
          DC.B    CR,LF,0
initMsg   DC.B     CR,LF
          ASC      'TEMPLEMON V1.20 installiert. Aufruf mit CONTROL-HELP'
          DC.B     CR,LF,0
vecmsg1   ACZ      'Restauriere Vektor auf '
vecmsg2   ACZ      ' / alter Wert '
*)

(*$ ? English:
  !UsrBPMsg ACZ  'Break by user trace program'
  !ExcMsg   ACZ  'Exception #'
  !Exc2Msg  ACZ  ' : '
  !ERRMSG   ACZ  'Error: '
  LOADMSG   DC.B CR,LF
            ACZ  'Loading from '
  SAVEMSG   DC.B CR,LF
            ACZ  'Saving from '
  !ENDMSG   ACZ  ', first unused address: '
  !RTNMSG   ACZ  'Return from GS'
  !TRCMSG   ACZ  'Trace'
  !FrmErMsg ACZ  'Format Error'
  !ILLMSG   ACZ  'Illegal instruction'
  !ILLIMSG  ACZ  'Illegal interrupt'
  !IRQMSG   ACZ  'Interrupt #'
  !TRAPMSG  ACZ  'Trap #'
  !TRPVMSG  ACZ  'TRAPV instruction'
  !CHKMSG   ACZ  'CHK instruction'
  !BRKMSG   ACZ  'BREAK instruction'
  !DIVMSG   ACZ  'Division by zero'
  !PRIVMSG  ACZ  'Privilege violation'
  !KBDEMSG  ACZ  'Keyboard break'
  !DirCMSG  ACZ  'Direct call (JSR)'
  !BPMSG    ACZ  'Entry by breakpoint'
  !BPNMSG   ACZ  'Entry by breakpoint #'
  !TRMMSG   ACZ  'Tracemode '
  NAKTMSG   ACZ  'not active'
  AKTMSG    ACZ  'active'
  !CFLMSG   ACZ  ' C:'
  !RMDMSG   ACZ  ' R:'
  !BEMSG    ACZ  'BUS ERROR at '
  !AEMSG    ACZ  'ADDRESS ERROR at '
  !SRMSG    ACZ  ' - SR:'
  !SSRMSG   ACZ  ' / super SR:'
  !EBFMSG   ACZ  ' / instruction:'
  ProtMsg   DC.B    CR,LF
            ACZ     'Protocol file '
  OpMsg     ACZ     'opened'
  ClosMsg   ACZ     'closed'
  IOResMsg  DC.B    CR,LF
            ACZ     'TOS error #'
  ShBPMsg   ACZ     'Breakpoint set at '
  SkipMsg   ACZ     'Skipped.'
  BPErrMsg  ACZ     'Unable to set breakpoint at '
  noBPsMsg  ACZ     'No breakpoints set'
  noMemMsg  DC.B  CR,LF
            ACZ     'No sufficient memory block available'
  OkMsg     DC.B  CR,LF
            ACZ     'OK.'
  notAllocMsg DC.B  CR,LF
            ACZ   "Block hasn't been allocated"
  noInstallMsg DC.B CR,LF
            ASC     'TEMPLEMON is already installed.'
            DC.B    CR,LF,0
  initMsg   DC.B     CR,LF
            ASC      'TEMPLEMON V1.20 installed. Activate with CONTROL-HELP'
            DC.B     CR,LF,0
  vecmsg1   ACZ      'Restore vector at '
  vecmsg2   ACZ      ' / old value '
*)


(*$ ? German:
ErrorList ACZ     "Unbekannte Funktion. '?' zeigt mehr..."
          ACZ     'Zahl erwartet'
          ACZ     'Zahl zu gross'
          ACZ     'Anfangsadr. ist groesser als Endadr.'
          ACZ     'Ueberfluessige Zeichen in Eingabe'
          ACZ     'Ungerade Adresse'
          ACZ     'SPACE erwartet'
          ACZ     'Falsche Registerbezeichnung'
          ACZ     'G-Funktion mit PC=0 nicht erlaubt'
          ACZ     'Leerstring nicht zulaessig'
          ACZ     'String zu lang'
          ACZ     'Fehlende Adresse / Parameter'
          ACZ     'BUS ERROR'
          ACZ     'ADDRESS ERROR'
          ACZ     'Allg. Syntax Fehler'
          ACZ     'Operator erwartet'
          ACZ     'Unzulaessiges Register'
          ACZ     'Zu viele Parameter'
          DC.B    0
          ACZ     'Undefinierter Fehler'
*)

(*$ ? English:
ErrorList ACZ     "Illegal command. Enter '?' for information"
          ACZ     'Number expected'
          ACZ     'Number too big'
          ACZ     'Start address exceeds end address'
          ACZ     'Illegal characters in command line'
          ACZ     'Odd address'
          ACZ     'SPACE expected'
          ACZ     'Wrong name for register'
          ACZ     'G-function with PC = 0 not allowed'
          ACZ     'Empty string is not allowed'
          ACZ     'String too long'
          ACZ     'Missing address / parameter'
          ACZ     'BUS ERROR'
          ACZ     'ADDRESS ERROR'
          ACZ     'Syntax error'
          ACZ     'Operator expected'
          ACZ     'Illegal register'
          ACZ     'Too many parameters'
          DC.B    0
          ACZ     'Undefined error'
*)
          SYNC

LocVarP   DS      4             ; ^ BSS  (A4)

KeyIORcV  ds      4             ; ADC
KbshiftV  ds      4             ; ADC
(*$? ADC:
IKBDSYSV  ds      4             ; ADC
OldMiKey  ds      4             ; ADC
;CtlAltHl  ds      2             ; ADC
*)

!CONSTAT  move.w    sr,-(sp)
          move.w    #$2700,sr
          move.l    a0,-(sp)            ; ADC: {
          move.l    KeyIORcV(pc),a0     ; Adresse des Keyboard-Buffers,
          move.w    8(a0),d0            ; + offset = n„chste leseposition
          cmp.w     6(a0),d0            ; Buffer gef�llt worden ?
          sne       d0
          ext.w     d0
          ext.l     d0
          move.l    (sp)+,a0
          move.w    (sp)+,sr
          rts                           ; }

!DIRCONIN move.w    sr,-(sp)
          move.w    #$2700,sr
          movem.l   a0/a1,-(sp)         ; ADC: {
          move.l    KeyIORcV(pc),a0     ; Adresse des Keyboard-Buffers,
          move.w    8(a0),d0            ; + offset = n„chste leseposition
          move.l    (a0),a1             ; Bufferadresse nach a1
          move.l    0(a1,d0.w),d0       ; SCAN / ASCII - Kode holen
          move.w    8(a0),6(a0)         ; Zeichen f�r TOS verschwundibus
          movem.l   (sp)+,a0/a1
          move.w    (sp)+,sr
          rts                           ; }

!KbShift  move.l    a0,-(sp)            ; ADC: {
          move.l    KbshiftV(pc),a0     ; Adresse des Shift-Status-Byte holen
          moveq     #0,d0               ; Bits 31-8 l”schen
          move.b    (a0),d0             ; Status in Bits 7-0
          move.l    (sp)+,a0
          rts                            ; }

pBasePage DS      4             ; ^ Base page
pFont8_16 DS      4             ; ^ Font
pFont8_8  DS      4             ; ^ Font
;pFont6_6  DS      4             ; ^ Font
pMonScreen
          DS      4             ; ^ Monitor-Screen
rMonScreen
          DS      2             ; ^ Monitor-Screen (nur Mid-Bytes!)
rNormScreen
          DS      4             ; ^ Normale Screen (nur Mid-Bytes!)
FontMode  DC.W    0             ; 0:Normaler Font, 1: 6*6-Font
ScrnMode  DC.W    0             ; 0:Monitor-Screen, 1:Normale Screen anzeigen

(* STE Register *)

Video_Base_Adress_Offset  DS  2 ; $FF8265
Video_Line_Adress_Offset  DS  2 ; $FF820F

(* Editierzeilen Variablen *)

HistoryStart    DS  4           ; ^ History Puffer Start
HistoryEnde     DS  4           ; ^ History Puffer Ende
HistoryAktuell  DS  4           ; ^ History Aktuelle Zeile zum Einf�gen
HistorySuchen   DS  4           ; ^ History Suchzeile
HistoryFill     DS  4           ; ^ Pointer

;
; *** Character aus Screen-buffer lesen ***
;
!ScrnGet  LEA     KEYBUF(A4),A0
          MOVE.W  CursorX(A4),D0
          MOVE.B  0(A0,D0.w),D0
          ANDI.L  #$FF,D0
          RTS
;
; *** Character auf Monitor-Screen darstellen ***
; Char in D0.B, Invers-Maske in D1.L (0 o. -1)
; (D0-D5/A0/A1)
;
DispTable DC.W        0,    0, 1280,   80, 2560,  160, 3840,  240, 5120,  320
          DC.W     6400,  400, 7680,  480, 8960,  560,10240,  640,11520,  720
          DC.W    12800,  800,14080,  880,15360,  960,16640, 1040,17920, 1120
          DC.W    19200, 1200,20480, 1280,21760, 1360,23040, 1440,24320, 1520
          DC.W    25600, 1600,26880, 1680,28160, 1760,29440, 1840,30720, 1920
          DC.W    32000, 2000

!DispChar ANDI.L  #$FF,D0

          (* !!!
          MOVE.W  FontMode(PC),D2   ; TST.W geht nicht
          BNE.L   Disp6_6       ; 6*6-Font darstellen
          *)

          TST     isTT(A4)
          BNE.S   Z400
          MOVE.B  $FF8260,D5
          BTST.L  #1,D5
          BEQ.L   Disp8_8       ; -> 200 Zeilen
Z400
          ; Parameter f. 400 Zeilen-Aufl”sung
          MOVE.L  pFont8_16(PC),A0

          ; Font-^ auf richtiges Zeichen bestimmen:
          ADDA.W  D0,A0
          ; Screenoffset := CursorY * 80/160 * 8/16 + CursorX * 1/2
          MOVE.W  CursorY(A4),D0
          TST     video_modus(A4)
          BEQ.L   disp_fast_mono
          ; D0 * 16 * video_line_bytes + CursorX
          ASL.W   #4,D0
          MULU    video_line_bytes(A4),D0
          MOVE.L  D2,-(SP)
          MOVE.W  CursorX(A4),D2
          EXT.L   D2
          ADD.L   D2,D0

          MOVE.L  pMonScreen(PC),A1
          ADDA.L  D0,A1

          ADDA.L  tmon_offset(A4),A1
          MOVE.L  A1,D2

          MOVE.W  video_line_bytes(A4),D0

          MOVE.B  (A0),(A1)
          ADDA.W  D0,A1
          MOVE.B  $0100(A0),(A1)       ;          MOVE.B  $0100(A0),0080(A1)
          ADDA.W  D0,A1
          MOVE.B  $0200(A0),(A1)       ;          MOVE.B  $0200(A0),0160(A1)
          ADDA.W  D0,A1
          MOVE.B  $0300(A0),(A1)       ;          MOVE.B  $0300(A0),0240(A1)
          ADDA.W  D0,A1
          MOVE.B  $0400(A0),(A1)       ;          MOVE.B  $0400(A0),0320(A1)
          ADDA.W  D0,A1
          MOVE.B  $0500(A0),(A1)       ;          MOVE.B  $0500(A0),0400(A1)
          ADDA.W  D0,A1
          MOVE.B  $0600(A0),(A1)       ;          MOVE.B  $0600(A0),0480(A1)
          ADDA.W  D0,A1
          MOVE.B  $0700(A0),(A1)       ;          MOVE.B  $0700(A0),0560(A1)
          ADDA.W  D0,A1
          MOVE.B  $0800(A0),(A1)       ;          MOVE.B  $0800(A0),0640(A1)
          ADDA.W  D0,A1
          MOVE.B  $0900(A0),(A1)       ;          MOVE.B  $0900(A0),0720(A1)
          ADDA.W  D0,A1
          MOVE.B  $0A00(A0),(A1)       ;          MOVE.B  $0A00(A0),0800(A1)
          ADDA.W  D0,A1
          MOVE.B  $0B00(A0),(A1)       ;          MOVE.B  $0B00(A0),0880(A1)
          ADDA.W  D0,A1
          MOVE.B  $0C00(A0),(A1)       ;          MOVE.B  $0C00(A0),0960(A1)
          ADDA.W  D0,A1
          MOVE.B  $0D00(A0),(A1)       ;          MOVE.B  $0D00(A0),1040(A1)
          ADDA.W  D0,A1
          MOVE.B  $0E00(A0),(A1)       ;          MOVE.B  $0E00(A0),1120(A1)
          ADDA.W  D0,A1
          MOVE.B  $0F00(A0),(A1)       ;          MOVE.B  $0F00(A0),1200(A1)

          TST     D1
          BEQ.L   Disp8_16E

          TST.W   EditModus(A4)
          BPL     Disp8_16O

          MOVE.L  D2,A1
          EORI.B  #-1,(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0080(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0160(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0240(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0320(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0400(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0480(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0560(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0640(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0720(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0800(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0880(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,0960(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,1040(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,1120(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,1200(A1)

Disp8_16E MOVE.L  (SP)+,D2
          RTS

Disp8_16O
          MOVE.L  D2,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,1120(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)            ;          EORI.B  #-1,1200(A1)
          MOVE.L  (SP)+,D2
          RTS

disp_fast_mono
          LEA     DispTable(PC),A1
          ASL.W   #2,D0
          MOVE.W  0(A1,D0.w),D0
          ADD.W   CursorX(A4),D0
          MOVE.L  pMonScreen(PC),A1
          ADDA.W  D0,A1
          MOVE.B  (A0),(A1)
          MOVE.B  $100(A0),0080(A1)
          MOVE.B  $200(A0),0160(A1)
          MOVE.B  $300(A0),0240(A1)
          MOVE.B  $400(A0),0320(A1)
          MOVE.B  $500(A0),0400(A1)
          MOVE.B  $600(A0),0480(A1)
          MOVE.B  $700(A0),0560(A1)
          MOVE.B  $800(A0),0640(A1)
          MOVE.B  $900(A0),0720(A1)
          MOVE.B  $A00(A0),0800(A1)
          MOVE.B  $B00(A0),0880(A1)
          MOVE.B  $C00(A0),0960(A1)
          MOVE.B  $D00(A0),1040(A1)
          MOVE.B  $E00(A0),1120(A1)
          MOVE.B  $F00(A0),1200(A1)

          TST     D1
          BEQ     disp_fast_mono_E

          TST.W   EditModus(A4)
          BPL     disp_fast_mono_O

          EORI.B  #-1,(A1)
          EORI.B  #-1,0080(A1)
          EORI.B  #-1,0160(A1)
          EORI.B  #-1,0240(A1)
          EORI.B  #-1,0320(A1)
          EORI.B  #-1,0400(A1)
          EORI.B  #-1,0480(A1)
          EORI.B  #-1,0560(A1)
          EORI.B  #-1,0640(A1)
          EORI.B  #-1,0720(A1)
          EORI.B  #-1,0800(A1)
          EORI.B  #-1,0880(A1)
          EORI.B  #-1,0960(A1)
          EORI.B  #-1,1040(A1)
disp_fast_mono_O
          EORI.B  #-1,1120(A1)
          EORI.B  #-1,1200(A1)

disp_fast_mono_E
          RTS

Disp8_8   ; Parameter f. 200 Zeilen-Aufl”sung
          MOVE.L  pFont8_8(PC),A0

          ; Font-^ auf richtiges Zeichen bestimmen:
          ADDA.W  D0,A0
          ; Screenoffset := CursorY * 80/160 * 8/16 + CursorX * 1/2
          MOVE.W  CursorY(A4),D0
          TST     video_modus(A4)
          BEQ.L   disp_fast_col

          ; D0 * 8 * video_line_bytes + (((CursorX & $FE) * 2) + (CursorX & 1))
          ASL.W   #3,D0
          MULU    video_line_bytes(A4),D0
          MOVE.L  D2,-(SP)
          MOVE.W  CursorX(A4),D2
          ANDI.L  #$FE,D2
          ASL.L   #1,D2
          ADD.L   D2,D0
          MOVE.W  CursorX(A4),D2
          ANDI.L  #1,D2
          ADD.L   D2,D0
          MOVE.L  pMonScreen(PC),A1
          ADDA.L  D0,A1

          ADDA.L  tmon_offset(A4),A1
          MOVE.L  A1,D2

          MOVE.W  video_line_bytes(A4),D0

          MOVE.B  (A0),(A1)
          ADDA.W  D0,A1
          MOVE.B  $0100(A0),(A1)        ;          MOVE.B  $0100(A0),0160(A1)
          ADDA.W  D0,A1
          MOVE.B  $0200(A0),(A1)        ;          MOVE.B  $0200(A0),0320(A1)
          ADDA.W  D0,A1
          MOVE.B  $0300(A0),(A1)        ;          MOVE.B  $0300(A0),0480(A1)
          ADDA.W  D0,A1
          MOVE.B  $0400(A0),(A1)        ;          MOVE.B  $0400(A0),0640(A1)
          ADDA.W  D0,A1
          MOVE.B  $0500(A0),(A1)        ;          MOVE.B  $0500(A0),0800(A1)
          ADDA.W  D0,A1
          MOVE.B  $0600(A0),(A1)        ;          MOVE.B  $0600(A0),0960(A1)
          ADDA.W  D0,A1
          MOVE.B  $0700(A0),(A1)        ;          MOVE.B  $0700(A0),1120(A1)

          TST     D1
          BEQ     Disp8_8E

          TST.W   EditModus(A4)
          BPL     Disp8_8O

          MOVE.L  D2,A1
          EORI.B  #-1,(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,0160(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,0320(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,0480(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,0640(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,0800(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,0960(A1)
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,1120(A1)

Disp8_8E  MOVE.L  (SP)+,D2
          RTS

Disp8_8O
          MOVE.L  D2,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          ADDA.W  D0,A1
          EORI.B  #-1,(A1)              ;          EORI.B  #-1,1120(A1)
          MOVE.L  (SP)+,D2
          RTS


disp_fast_col
          LSL.W   #8,D0
          MOVE.W  D0,D5
          LSL.W   #2,D0
          ADD.W   D5,D0
          MOVE.W  CursorX(A4),D4
          MOVE.W  D4,D5
          ANDI.W  #$FFFE,D4
          LSL.W   #1,D4
          ADD.W   D4,D0
          ANDI.W  #1,D5
          ADD.W   D5,D0
          MOVE.L  pMonScreen(PC),A1
          ADDA.W  D0,A1

          MOVE.B  (A0),(A1)
          MOVE.B  $100(A0),0160(A1)
          MOVE.B  $200(A0),0320(A1)
          MOVE.B  $300(A0),0480(A1)
          MOVE.B  $400(A0),0640(A1)
          MOVE.B  $500(A0),0800(A1)
          MOVE.B  $600(A0),0960(A1)
          MOVE.B  $700(A0),1120(A1)

          TST.W   D1
          BEQ     disp_fast_col_E

          TST.W   EditModus(A4)
          BPL     disp_fast_col_O

          EORI.B  #-1,(A1)
          EORI.B  #-1,0160(A1)
          EORI.B  #-1,0320(A1)
          EORI.B  #-1,0480(A1)
          EORI.B  #-1,0640(A1)
          EORI.B  #-1,0800(A1)
          EORI.B  #-1,0960(A1)
disp_fast_col_O
          EORI.B  #-1,1120(A1)

disp_fast_col_E
          rts

(*
Disp6Mask DC.L    00000000111111000000000000000000%
          DC.L    00000000001111110000000000000000%
          DC.L    00000000000011110000000011000000%
          DC.L    00000000000000110000000011110000%

Disp6_6   ; D0 (Character) * 6 :
          ASL     #1,D0
          MOVE    D0,D3
          ASL     #1,D0
          ADD     D3,D0
          ; D0 / 32 :
          ROR.L   #5,D0
          
          ; Font-^ auf richtiges Zeichen bestimmen:
          MOVE.L  pFont6_6(PC),A0
          ADDA.W  D0,A0
          
          SWAP    D0            ; Rest der Division (MOD 32)
          ROL     #5,D0         ; D0 : Bit-Offset in Scanbyte
          LEA     Disp6Mask(PC),A1
          ASL.W   #2,D0
          MOVE.L  0(A1,D0.W),D0 ; D0 : Maske f. Scanwort
          AND.L   D0,D1         ; invers-Maske mit Scan-Maske ANDen
          
          
          MOVEQ   #6,D2         ; Anzahl Scanlines
          
          MOVEQ   #80,D3        ; Offset z. n„chsten Videozeile
          MOVE    CursorX(A4),D4
          
          BTST    #1,$FF8260    ; Aufl”sung ?
          BNE     Disp6C0       ; -> 400 Zeilen
          
          MOVE.W  #160,D3       ; Offset z. n„chsten Videozeile
          ASL     #1,D4
          
Disp6C0   ; Screenoffset := CursorY * 80/160 * 6 + CursorX * 1/2
          MOVE.W  CursorY(A4),D5
          MULU    D3,D5
          MULU    D2,D5
          ADD     D4,D5
          MOVE.L  pMonScreen(PC),A1
          ADDA.W  D5,A1
          BRA     Disp6C1
          
Disp6L0   MOVE.B  (A0)+,D4
          SWAP    D4
          MOVE.B  (A0)+,D4
          AND.L   D0,D4         ; Char aus Font mit Maske ausfiltern
          
          MOVE.B  (A1)+,D5
          SWAP    D5
          MOVE.B  (A1)+,D5
          NOT.L   D0            ; Maske invertieren
          
          AND.L   D0,D5         ; aus Video-Wort Char-Bereich l”schen
          OR.L    D5,D4         ; und mit Char aus Font �berlagern
          ;!! EOR.L   D1,D4         ; invers-Maske
          
          MOVE.B  D4,-(A1)
          SWAP    D4
          MOVE.B  D4,-(A1)
          
          NOT.L   D0            ; Maske zur�ck
          ADDA.W  #$C0-2,A0     ; Offset z. n„chsten Scanline
          ADDA.W  D3,A1         ; Offset z. n„chsten Videozeile
Disp6C1   DBRA    D2,Disp6L0
          RTS
*)

(*
Disp6Mask DC.L    00000000111111000000000000000000%
          DC.L    00000000000000110000000011110000%
          DC.L    00000000000011110000000011000000%
          DC.L    00000000001111110000000000000000%

Disp6_6   ; D0 (Character) * 6 :
          ASL     #1,D0
          MOVE    D0,D3
          ASL     #1,D0
          ADD     D3,D0
          ; D0 / 8 :
          ROR.L   #3,D0
          ; Font-^ auf richtiges Zeichen bestimmen:
          MOVE.L  pFont6_6(PC),A0
          ADDA.W  D0,A0
          SWAP    D0            ; Rest der Division (MOD 8)
          ROL     #3,D0         ; D0 : Bit-Offset in Scanbyte
          LEA     Disp6Mask(PC),A1
          ASL.W   #1,D0
          MOVE.L  0(A1,D0.W),D0 ; D0 : Maske f. Scanwort
          AND.L   D0,D1         ; invers-Maske mit Scan-Maske ANDen
          
          
          MOVEQ   #6,D2         ; Anzahl Scanlines
          
          MOVEQ   #80,D3        ; Offset z. n„chsten Videozeile
          MOVE    CursorX(A4),D4
          
          BTST    #1,$FF8260    ; Aufl”sung ?
          BNE     Disp6C0       ; -> 400 Zeilen
          
          MOVE.W  #160,D3       ; Offset z. n„chsten Videozeile
          ASL     #1,D4
          
Disp6C0   ; Screenoffset := CursorY * 80/160 * 6 + CursorX * 1/2
          MOVE.W  CursorY(A4),D5
          MULU    D3,D5
          MULU    D2,D5
          ADD     D4,D5
          MOVE.L  pMonScreen(PC),A1
          ADDA.W  D5,A1
          BRA     Disp6C1
          
Disp6L0   MOVE.B  (A0)+,D4
          SWAP    D4
          MOVE.B  (A0)+,D4
          AND.L   D0,D4         ; Char aus Font mit Maske ausfiltern
          
          MOVE.B  (A1)+,D5
          SWAP    D5
          MOVE.B  (A1)+,D5
          NOT.L   D0            ; Maske invertieren
          
          AND.L   D0,D5         ; aus Video-Wort Char-Bereich l”schen
          OR.L    D5,D4         ; und mit Char aus Font �berlagern
          ;!! EOR.L   D1,D4         ; invers-Maske
          
          MOVE.B  D4,-(A1)
          SWAP    D4
          MOVE.B  D4,-(A1)
          
          NOT.L   D0            ; Maske zur�ck
          ADDA.W  #$C0-2,A0     ; Offset z. n„chsten Scanline
          ADDA.W  D3,A1         ; Offset z. n„chsten Videozeile
Disp6C1   DBRA    D2,Disp6L0
          RTS
*)


ClearEol  MOVE    CursorX(A4),-(A7)
ClrEolL0  MOVE    CursorX(A4),D0
          CMP     Rows(A4),D0
          BCS     ClEolC0
          MOVE    (A7)+,CursorX(A4)
          RTS
ClEolC0   MOVEQ   #0,D1
          MOVEQ   #' ',D0
          BSR     DispChar
          ADDQ.W  #1,CursorX(A4)
          BRA     ClrEolL0
          
ClearScrn CLR.W   CursorX(A4)
          CLR.W   CursorY(A4)
          MOVEM.L A0/D0-D2,-(A7)
          MOVE.L  pMonScreen(PC),A0
          TST     video_modus(A4)
          BEQ     FastClearScrn
          MOVE.L  video_memory(A4),D0
          ADD.L   #256,D0             ; die Zeile Reserve mitschw„rzen
          SUBQ.L  #1,D0
          MOVEQ.L #-1,D1              ; Bildschirm schw„rzen
          CMPI.W  #1,video_plane(A4)
          BNE     clrScrnL0
          MOVE.B  mono_0(PC),D2
          ANDI.B  #1,D2
          BNE     clrScrnL0
          CLR.L   D1
clrScrnL0 MOVE.B  D1,(A0)+
          DBRA    D0,clrScrnL0

          MOVE.L  pMonScreen(PC),A0
          ADDA.L  tmon_offset(A4),A0
eine_zeile
          MOVE.W  Rows(A4),D0
          MULU    video_plane(A4),D0
          SUBQ.W  #1,D0
          MOVE.W  Lines(A4),D1
          MULU    CharHeight(A4),D1
          SUBQ.W  #1,D1
do_zeile
          MOVE.W  D0,D2               ; Z„hler initialisieren
zeile_loop
          CLR.B   0(A0,D2.w)
          DBRA    D2,zeile_loop
          MOVE.W  video_line_bytes(A4),D2
          EXT.L   D2
          ADDA.L  D2,A0
          DBRA    D1,do_zeile
end_clrscr
          MOVEM.L (A7)+,A0/D0-D2
          RTS

FastClearScrn
          MOVE.L  #7999,D0            ; 32000 / 4 -1
FastClearScrnLoop
          CLR.L   (A0)+
          DBRA    D0,FastClearScrnLoop
          BRA     end_clrscr


ClearEoS  BSR     ClearEol
          MOVE    CursorX(A4),-(A7)
          MOVE    CursorY(A4),-(A7)
          CLR.W   CursorX(A4)
ClrEosL   ADDQ.W  #1,CursorY(A4)
          MOVE    CursorY(A4),D0
          CMP     Lines(A4),D0
          BCC     ClrEosE
          BSR     ClearEol
          BRA     ClrEosL
ClrEosE   MOVE    (A7)+,CursorY(A4)
          MOVE    (A7)+,CursorX(A4)
ScrnRTS   RTS
          
CopyLine  MOVEM.L D0/A2/A3,-(SP)      ; 80 Bytes von A2 nach A3 kopieren
          MOVE.L  A2,D0               ; falls monchrom, sonst 160 Bytes
          BTST.L  #0,D0               ; die Register bleiben unangetastet
          BNE     CopyLine1           ; man k”nnte die Routine noch soweit
          MOVE.L  A3,D0               ; erweitern, daž in Abh„ngigkeit der
          BTST.L  #0,D0               ; Chars pro Zeile entsprechend viele
          BNE     CopyLineWorse       ; Bytes kopiert werden (etwa durch
                                      ; Anspringen mittels einer Sprungta-
                                      ; belle).
CopyLineGerade
          BSR     CopyLine10
          CMPI.W  #1,video_plane(A4)
          BEQ     EndCopyLine
          BSR     CopyLine10
EndCopyLine
          MOVEM.L (SP)+,D0/A2/A3
          RTS

CopyLine1
          MOVE.L  A3,D0
          BTST.L  #0,D0
          BEQ     CopyLineWorse

CopyLineUngerade
          BSR     CopyLine15
          CMPI.W  #1,video_plane(A4)
          BEQ     EndCopyLine
          BSR     CopyLine15
          BRA     EndCopyLine

CopyLineWorse
          BSR     CopyLine20
          CMPI.W  #1,video_plane(A4)
          BEQ     EndCopyLine
          BSR     CopyLine20
          BRA     EndCopyLine

CopyLine10
          MOVE.L  (A2)+,(A3)+
CopyLine11
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          MOVE.L  (A2)+,(A3)+
          RTS

CopyLine15
          MOVE.B  (A2)+,(A3)+
          BSR     CopyLine11
          MOVE.W  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          RTS

CopyLine20
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          MOVE.B  (A2)+,(A3)+
          RTS

TextLine                                  ; Liefert in D0 Offset zur n„ch-
          MOVE.L  D2,-(SP)                ; sten Textzeile zur�ck,
          MOVE.W  video_line_bytes(A4),D1 ; in D1 Bytes pro Videozeile,
          ANDI.L  #$FFFF,D1               ; in A0 Pointer auf Bildstart,
;          MOVE.W  #200,D2                 ; in A1 Pointer auf Bildende.
;          MOVE.W  #8,D0
;          CMPI.W  #1,video_plane(A4)
;          BNE     TextColor
;          MOVE.W  #400,D2
;          MOVE.W  #16,D0
          MOVE.W  CharHeight(A4),D0
          MOVE.W  Lines(A4),D2
          MULU.W  D0,D2
TextColor
          MULU.W  D1,D2
          MULU.W  D1,D0
          MOVE.L  pMonScreen(PC),A0
          ADDA.L  tmon_offset(A4),A0
          MOVE.L  A0,A1
          ADDA.L  D2,A1
          MOVE.L  (SP)+,D2
          RTS


ScrollUp  TST     video_modus(A4)
          BEQ     FastScrollUp
          MOVEM.L A0-A3/D0/D1,-(SP)
          BSR     TextLine
          MOVE.L  A0,A2
          MOVE.L  A0,A3
          ADDA.L  D0,A2
UpLoop    BSR     CopyLine
          ADDA.L  D1,A2
          ADDA.L  D1,A3
          CMPA.L  A1,A2
          BLT     UpLoop
          MOVEM.L (SP)+,A0-A3/D0/D1
          RTS

FastScrollUp
          MOVEM.L A0-A6/D0-D7,-(SP)
          MOVE.L  pMonScreen(PC),A0
          MOVE.L  A0,A1
          ADDA.W  #1280,A1
          MOVE.W  #25,D0
FastScrollUpLoop
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,48(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,96(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,144(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,192(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,240(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,288(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,336(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,384(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,432(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,480(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,528(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,576(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,624(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,672(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,720(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,768(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,816(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,864(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,912(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,960(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,1008(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,1056(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,1104(A0)
          ADDA.W  #1152,A0
          DBRA    D0,FastScrollUpLoop
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,48(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,96(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,144(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,192(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,240(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,288(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,336(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,384(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,432(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,480(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,528(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,576(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,624(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,672(A0)
          MOVEM.L (A1)+,A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,720(A0)
          MOVEM.L (SP)+,A0-A6/D0-D7
          RTS
          
ScrollDown
          TST     video_modus(A4)
          BEQ     FastScrollDown
          MOVEM.L A0-A3/D0/D1,-(SP)
          BSR     TextLine
          MOVE.L  A1,A2
          MOVE.L  A1,A3
          SUBA.L  D0,A3
DownLoop  BSR     CopyLine
          SUBA.L  D1,A2
          SUBA.L  D1,A3
          CMPA.L  A0,A2
          BGT     DownLoop
          MOVEM.L (SP)+,A0-A3/D0/D1
          RTS

FastScrollDown
          MOVEM.L A0-A6/D0-D7,-(SP)
          MOVE.L  pMonScreen(PC),A0
          ADDA.W  #$7D00,A0
          MOVE.L  A0,A1
          SUBA.W  #1280,A1
          MOVE.W  #25,D0
FastScrollDownLoop
          MOVEM.L (A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -48(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -96(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -144(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -192(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -240(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -288(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -336(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -384(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -432(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -480(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -528(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -576(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -624(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -672(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -720(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -768(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -816(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -864(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -912(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -960(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -1008(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -1056(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -1104(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          SUBA.W  #1152,A1
          DBRA    D0,FastScrollDownLoop
          MOVEM.L (A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -48(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -96(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -144(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -192(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -240(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -288(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -336(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -384(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -432(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -480(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -528(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -576(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -624(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -672(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L -720(A1),A2-A6/D1-D7
          MOVEM.L A2-A6/D1-D7,-(A0)
          MOVEM.L (SP)+,A0-A6/D0-D7
          RTS

          
CursorDown
          ADDQ.W  #1,CursorY(A4)
          MOVE    CursorY(A4),D0
          CMP     Lines(A4),D0
          BCS     CurDE
          MOVE.W  Lines(A4),D0
          SUBQ    #1,D0
          MOVE    D0,CursorY(A4)
          BSR     ScrollUp
CurDC     MOVE    CursorX(A4),-(A7)
          CLR.W   CursorX(A4)
          BSR     ClearEoL
          MOVE    (A7)+,CursorX(A4)
CurDE     RTS
          
CursorUp  SUBQ    #1,CursorY(A4)
          BCC     CurDE
          CLR     CursorY(A4)
          BSR     ScrollDown
          BRA     CurDC
          
ChkCursor MOVE    CursorX(A4),D0
          CMP     Rows(A4),D0
          BCS     ScrnRTS
          CLR.W   CursorX(A4)
          BRA     CursorDown
          
IncCursor ADDQ.W  #1,CursorX(A4)
          MOVE    CursorX(A4),D0
          CMP     Rows(A4),D0
          BLS     ScrnRTS
          CLR.W   CursorX(A4)
          BRA     CursorDown
          
DecCursor SUBQ.W  #1,CursorX(A4)
          BCC     ScrnRTS
          MOVE    Rows(A4),CursorX(A4)
          SUBQ.W  #1,CursorX(A4)
          BRA     CursorUp

BackSpace BSR     DecCursor
          MOVEQ   #0,D1
          MOVEQ   #' ',D1
          BRA     DispChar
          
ScrnCurOn MOVE.L  BlinkRate(PC),CursorCnt(A4)
          BSR     ChkCursor
          TST     CursorState(A4)
          BNE     CurOnE
          BSR     ScrnGet
          MOVEQ   #-1,D1
          BSR     DispChar
          MOVE    #1,CursorState(A4)
CurOnE    RTS

ScrnCurOff
          MOVE.L  BlinkRate(PC),CursorCnt(A4)
          TST     CursorState(A4)
          BEQ     CurOffE
          MOVE    D0,-(A7)
          BSR     ScrnGet
          MOVEQ   #0,D1
          BSR     DispChar
          MOVE    (A7)+,D0
          CLR     CursorState(A4)
CurOffE   RTS

ScrnCR    CLR.W   CursorX(A4)
          RTS
          
!ScrnOut  BSR     ScrnCurOff
          BTST    #13,D7        ; DirConOut ?
          BNE     ScrnOutC0
          CMPI    #SPC,D0
          BCC     ScrnOutC0
          CMPI    #CR,D0
          BEQ     ScrnCR
          CMPI    #LF,D0
          BEQ     CursorDown
          CMPI    #BS,D0
          BEQ     BackSpace
          CMPI    #FF,D0
          BEQ     ClearScrn
          CMPI    #ClEol,D0
          BEQ     ClearEoL
          CMPI    #ClEoS,D0
          BEQ     ClearEoS
          CMPI    #Con,D0
          BEQ     ScrnCurOn
          CMPI    #Coff,D0
          BEQ     ScrnCurOff
          RTS
          
ScrnOutC0 MOVE    D0,-(A7)
          BSR     ChkCursor
          MOVE    (A7)+,D0
          MOVEQ   #0,D1
          BSR     DispChar
          BRA     IncCursor
          
!ScrnOutput                       ; Bildschirmausgabe ohne Controllzeichen!
          BSR     ScrnCurOff
          MOVE    D0,-(SP)
          BSR     ChkCursor
          MOVE    (SP)+,D0
          MOVEQ   #0,D1
          BRA     DispChar


!CursorOn MOVEM.L D0-D5/A0/A1,-(A7)
          BSR     ScrnCurOn
          MOVEM.L (A7)+,D0-D5/A0/A1
          RTS

!CursorOff
          MOVEM.L D0-D5/A0/A1,-(A7)
          BSR     ScrnCurOff
          MOVEM.L (A7)+,D0-D5/A0/A1
CurBlnkE  RTS

!CursorBlink
          TST.L   CursorCnt(A4)
          BEQ     CurBlnkE              ; kein Blinken, wenn Rate = 0
          SUBQ.L  #1,CursorCnt(A4)
          BNE     CurBlnkE
          TST     CursorState(A4)
          BEQ     CursorOn
          BRA     CursorOff

!Prt      ANDI.W  #$FF,D0
          MOVE.B  D0,ch(A4)
          MOVEM.L D0-D5/A0-A2,-(A7)
          
          TST.B   NoScrDisp(A4)
          BNE     noPrt
          BSR     ScrnOut
noPrt
          MOVE.B  ch(A4),D0
          ANDI    #$7F,D0
          BCLR    #13,D7          ; Ctrl-Zeichen sichtbar ?
          BEQ     noPConv
          CMPI.B  #' ',D0
          BCC     noPConv
          MOVEQ   #'.',D0
noPConv   TST.W   PrHandle(A4)
          BEQ     PrtE
          CMPI.B  #32,D0
          BCC     chrOk
          CMPI.B  #FF,D0
          BEQ     chrOk           ; LF wird ignoriert, stattdessen immer bei CR:
          CMPI.B  #CR,D0
          BNE     PrtE
chrOk     MOVE.B  D0,ch(A4)
          LEA     ch(A4),A0
          MOVE.L  A0,-(A7)
          MOVE.L  #1,-(A7)
          MOVE    PrHandle(A4),-(A7)
          MOVE    #$40,-(A7)
          TRAP    #1
          ADDA.W  #12,A7
          TST.L   D0
          BMI     PrtE0
          CMPI.B  #CR,ch(A4)
          BNE     PrtE
          MOVE.B  #LF,D0
          BRA     chrOK
PrtE0     BSR.L   PrntCloseErr
PrtE      MOVEM.L (A7)+,D0-D5/A0-A2
          RTS
;
;
;
!PRTPRMPT BSR.L   PRTCRLF
          MOVEQ   #PROMPT,D0
          BRA     Prt
;
!PRTCRLF  BCLR    #11,D7
          BNE.L   PCRLFC0         ; KEIN LF AUSGEBEN
          
          MOVEQ   #ClEol,D0       ; ZEILE AB CURSOR LOESCHEN
          BSR     PRT
          MOVEQ   #CR,D0
          BSR     PRT
          MOVEQ   #LF,D0
          BRA     PRT
          
PCRLFC0   MOVEQ   #CR,D0
          BSR     PRT
          MOVEQ   #ClEol,D0       ; ZEILE ganz LOESCHEN
          BRA     PRT
;
!PRTSPC   MOVEQ   #SPC,D0
          BRA     PRT
;
!PRTMSPCL BSR     PRTSPC
!PRTMSPC  DBF     D1,PRTMSPCL     ; (D1)+1 SPACES AUSGEBEN
          RTS
;
!PRTSTR   MOVE.B  (A1)+,D0
          BNE     PRTSTRC0
          RTS
PRTSTRC0  BSR     PRT
          BRA     PRTSTR
;
!PRTADR   TST.W   is20(A4)
          BNE     PrtLong
          SWAP    D0
          BSR.S   PRTBYTE
          BRA.S   PRTLONG1
;
!PRTLONG  SWAP    D0
          BSR.S   PRTWORD
!PRTLONG1 SWAP    D0
;
!PRTWORD  MOVE.W  D0,-(A7)
          LSR.W   #8,D0
          BSR.S   PRTBYTE
          MOVE.W  (A7)+,D0
;
!PRTBYTE  MOVE.B  D0,-(A7)
          LSR.B   #4,D0
          BSR.S   PRTNIBL
          MOVE.B  (A7)+,D0
;
!PRTNIBL  ANDI.B  #$F,D0
          ORI.B   #$30,D0
          CMPI.B  #'9',D0
          BLS.S   PRTNIBL1
          ADDQ.B  #7,D0
!PRTNIBL1 BRA     Prt

FrmState  MOVE.L  D0,-(A7)
          MOVEQ   #'(',D0
          BSR.W   outchar
          MOVEQ   #'0',D0
          ADD     StkFrm,D0
          BSR.W   outchar
          MOVEQ   #')',D0
          BSR.W   outchar
          MOVE.L  (A7)+,D0
          RTS

!Wvbl     ; Warten auf Vertical Blank
          MOVEP.W 5(A1),D1
          CMP.W   D0,D1
          BEQ     Wvbl
Wvbl2     MOVEP.W 5(A1),D1
          CMP.W   D0,D1
          BNE     Wvbl2
          RTS

!NormScrn ; Normale Screen anzeigen
          MOVE    SR,-(A7)
          MOVE    #$2700,SR
          MOVEM.L D0/A0/A1,-(A7)
          LEA     $FF8200,A1
          MOVEP.W 1(A1),D0
          CMP.W   rMonScreen(PC),D0
          BNE.L   MonScrE0
          LEA     farbe(A4),A0          ; Farben restaurieren
          MOVE.W  (A0)+,$40(A1)
          TST     isTT(A4)
          BEQ     MonScrnormST
          MOVE.W  (A0)+,$FF85FC
          MOVE.W  (A0)+,$FF85FE
          BRA     MonScrC0
MonScrnormST
          MOVE.W  (A0)+,$42(A1)
          MOVE.W  (A0)+,$44(A1)
          MOVE.W  (A0),$46(A1)
MonScrC0  BSR     Wvbl
          MOVE.B  rNormScreen+2(PC),$60(A1) ; alte Aufl”sung zur�ck
          TST     isTT(A4)
          BEQ     NormScrC1
          MOVE.W  TT_Shift_Mode(A4),$62(A1)
NormScrC1 MOVE.W  rNormScreen(PC),D0        ; Video Base zur�ck
          MOVEP.W D0,1(A1)
          TST     isTT(A4)
          BNE     NormScrC01
          TST     isSTE(A4)
          BEQ     MonScrC01                 ; normaler ST kein LOW v_base
NormScrC01
          MOVE.B  rNormScreen+3(PC),D0      ; LOW Video Base zur�ck
          MOVE.B  D0,$FF820D
          MOVE.B  Video_Base_Adress_Offset(PC),D0
          MOVE.B  D0,$FF820F
          MOVE.B  Video_Line_Adress_Offset(PC),D0
          MOVE.B  D0,$FF8265
MonScrC01
          TST     isTT(A4)
          BNE     MonScrE0
          TST     isSTE(A4)
          BNE     MonScrE0
          BSR.L   OverScanTest   ; normaler ST: OverScan zur�ck?
          CMP.W   entry_video_modus(A4),D0 ; gegebnenfalls befindet sich
          BEQ     MonScrE0   ; TempleMon auch im OverScan Modus
          TST.W   entry_video_modus(A4)  ; vgl. HyperScreen!
          BEQ     MonScrNorm
          BSR.L   BigScreen
          BRA     MonScrE0
MonScrNorm
          BSR.L   SmallScreen
MonScrE0  MOVEM.L (A7)+,D0/A0/A1
          MOVE    (A7)+,SR
          RTS

!MonScrn  ; Monitor-Screen anzeigen
          MOVE    SR,-(A7)
          MOVE    #$2700,SR
          MOVEM.L D0/A0/A1,-(A7)
          LEA     $FF8200,A1
          MOVEP.W 1(A1),D0
          CMP.W   rMonScreen(PC),D0
          BEQ     MonScrE0              ; aktueller Schirm gleich TempleMon Schirm
          LEA     rNormScreen(PC),A0
          MOVE    D0,(A0)               ; video_base sichern
          CLR.W   video_modus(A4) ; erst mal von Standard Schirm ausgehen!
          TST     isTT(A4)  ; TT ?
          BNE     save_res1  ; dann kein OverScan
          TST     isSTE(A4)  ; STE ?
          BNE     save_res1             ; dann kein OverScan
          ; normaler ST: OverScan untersuchen
          MOVE.W  D0,-(SP)  ; D0 sichern
          BSR.L   OverScanTest  ; OverScan Modus ermitteln
          MOVE.W  D0,entry_video_modus(A4)  ; und abspeichern
          MOVE.W  D0,video_modus(A4)
          BEQ.S   save_res              ; Small Screen ist aktiv -> zu reg.
          TST.W   autoswitch(A4) ; AutoSwitchhardware ?
          BEQ.S   save_res              ; keine AutoSwitch Hardware ->reg.
          BSR.L   SmallScreen   ; AutoSwitch: auf kleinen Schirm schalten!
          CLR.W   video_modus(A4) ; AutoSwitch: Standard Schirm nutzen!
save_res
          MOVE.W  (SP)+,D0
save_res1
          LEA     rNormScreen(PC),A0
          MOVE.B  $60(A1),2(A0)         ; Aufl”sung retten (wg. Farbe)
          TST     isTT(A4)
          BEQ     MonScrCSTE
          MOVE.W  $62(A1),TT_Shift_Mode(A4)
          BRA     MonScrCTT             ; TT Schirm !!!
MonScrCSTE
          TST.W   isSTE(A4)
          BEQ     MonScrC11             ; kein tt & STE
MonScrCTT
          MOVE.B  $FF820D,3(A0)         ; Video Base LOW des STE's & TT's auf 0!
          LEA     Video_Base_Adress_Offset(PC),A0
          MOVE.B  $FF820F,(A0)
          LEA     Video_Line_Adress_Offset(PC),A0
          MOVE.B  $FF8265,(A0)
MonScrC11

          TST     isTT(A4)
          BNE     MonScrC2              ; bei TT immer 640 * 400
          MOVE.B  $60(A1),D0            ; Farbe od. Mono?
          BTST.L  #1,D0
          BNE     MonScrC2  ; Monochrom!
          MOVE.B  #1,$60(A1)            ; auf 640 * 200, falls Farbmodus
          MOVE.W  #8,CharHeight(A4)
          BRA     MonScrC1
MonScrC2  MOVE.B  #2,$60(A1)            ; auf 640 * 400 sonst
          MOVE.W  #16,CharHeight(A4)
MonScrC1  MOVE.W  rMonScreen(PC),D0     ; TempleMon Schirm setzen
          MOVEP.W D0,1(A1)
          TST     isTT(A4)
          BNE     MonScrC3
          TST     isSTE(A4)
          BEQ     MonScrC4              ; nur ST dann zu Farbe setzen
MonScrC3  CLR.B   $0D(A1)               ; LOW des Video_Base des STE's & TT
          CLR.B   $0F(A1)
          CLR.B   $65(A1)
MonScrC4
          LEA     farbe(A4),A0
          MOVE.W  $40(A1),(A0)         ; die ersten vier Farbregister retten
          MOVE.W  $42(A1),2(A0)
          MOVE.W  $44(A1),4(A0)
          MOVE.W  $46(A1),6(A0)
          TST     isTT(A4)
          BNE     MonScrC001TT         ; TT nur Monochrom Farbe!
          BTST    #1,$60(A1)
          BNE     MonScrC001           ; Monochrom bei ST od. STE
          LEA     color_0(PC),A0       ; Farben setzen
          MOVE.W  (A0),$40(A1)
          MOVE.W  2(A0),$42(A1)
          MOVE.W  4(A0),$44(A1)
          MOVE.W  6(A0),$46(A1)
          BRA     MonScr12
MonScrC001TT
          MOVE.W  $FF85FC,2(A0)  ; TT Farbreg 254 & 255 retten (Duochrome)
          MOVE.W  $FF85FE,4(A0)
          MOVE.W  tt_mono_0(PC),$FF85FC
          MOVE.W  tt_mono_1(PC),$FF85FE
          MOVE.W  mono_0(PC),D0
          ANDI.W  #1,D0
          ASL.W   #1,D0
          MOVE.W  D0,$40(A1)
          BRA     MonScrE0
MonScrC001
          MOVE.W  mono_0(PC),D0
          ANDI.W  #1,D0
          MOVE.W  D0,$40(A1)
MonScr12
          BRA     MonScrE0

;*** COMMAND TABLE

!CMDTBEG  ASC     'MIVCDBGR;O:'
          DC.B    $27
          ASC     'HFTPSQ&?L'
!CMDTEND
          SYNC
          
;*** COMMAND VECTORS

!CMDVEC   BRA.L ComdM
          BRA.L ComdI
          BRA.L ComdV
          BRA.L ComdC
          BRA.L ComdD
          BRA.L ComdB
          BRA.L ComdG
          BRA.L ComdR
          BRA.L ComdSEMK
          BRA.L ComdO
          BRA.L ComdDOPP
          BRA.L ComdHKOM
          BRA.L ComdH
          BRA.L ComdF
          BRA.L ComdT
          BRA.L ComdP
          BRA.L ComdS
          BRA.L ComdQ
          BRA.L ComdDEZ
          BRA.L ComdFRAG
          BRA.L ComdL

;*** REGISTER TABELLEN

!REGTAB ASC 'SR D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 A3 A4 A5 A6 A7 PC USPSSPBEVAEV'
REGTABEND

!SRTAB    DC.B 'T',15,1,'S',13,1,'I',8,7,'X',4,1,'N',3,1,'Z',2,1,'V',1,1
          DC.B 'C',0,1,0

          SYNC

; Darf D3 und Bit 2 in D7 nicht „ndern (wg. CRU):
!PRTREG   BSR     PrtSPC
          BTST    #0,D7
          BNE.S   PRTRC1        ; Nur Namen ausgeben
          BTST    #2,D7
          BEQ.S   PRTRC1        ; nicht Flags ausgeben
          CMPI.B  #TNRSR,D2
          BNE.S   PRTRC1
          BRA.L   PRTSRBIN      ; SR als Flags ausgeben
          
!PRTRC1   LEA     REGTAB(PC),A1
          
          ; Test, ob tabellarische Ausgabe, dann nicht Regnamen ausgeben
          BTST    #10,D7
          BEQ.S   PRTRC6
          CMPI.B  #TNrD0,D2
          BCS.S   PRTRC6
          CMPI.B  #TNrA7,D2
          BLS.S   PRTRC5
          
!PRTRC6   ; Regnamen ausgeben
          CMPI.B  #TNrSR,D2       ; SR ?
          BNE     PrtRC2
          BTST    #2,D7           ; als Flags ausgeben ?
          BEQ     PrtRC2
          
          ; nur 'F' ausgeben:
          MOVEQ   #'F',D0
          BSR     Prt
          BRA     PRTRC4          ; Nur Name sollte ausgegeben werden.
          
!PRTRC2   MULU    #3,D2
          MOVE.B  0(A1,D2.W),D0   ; PRT REG.NAME
          BSR     Prt
          MOVE.B  1(A1,D2.W),D0
          BSR     Prt
          MOVE.B  2(A1,D2.W),D0
          CMPI.B  #' ',D0
          BEQ     PRTRC7
          BSR     Prt
!PRTRC7   DIVU    #3,D2
          
          BTST    #0,D7
          BNE.S   PRTRC4          ; Nur Namen ausgeben -> fertig
          
          MOVEQ   #'=',D0
          BSR     Prt

!PRTRC5   LEA     REGBEG(A4),A1       ; REGISTERADR. BERECHNEN
          BSR.L   ChkRegNo
          LSL.W   #2,D2
          MOVE.L  0(A1,D2.W),D0                  ; REG.INHALT LADEN
          CMPI.B  #TNRSR+TNRSR+TNRSR+TNRSR,D2    ; SR AUSGEBEN ?
          BEQ.S   PRTRW                          ; JA,DANN NUR 2 BYTE
          BSR     PrtLONG
          BRA.S   PRTRC4
!PRTRW    BSR     PrtWORD
!PRTRC4   RTS
          

!PRTMSG   BSR     PrtCRLF
          
          BTST    #2,EntryMod(A4)
          BEQ.S   PRTMSGC5
          
          ; 'Exception' ausgeben
          LEA     ExcMsg(PC),A1
          BSR     PrtSTR
          MOVE    ExcNo(A4),D0
          BSR     PrtBYTE
          LEA     Exc2Msg(PC),A1
          BSR     PrtSTR
          
!PRTMSGC5 MOVEA.L EntryMsg(A4),A1     ; PRT. ENTRY-MELDUNG
          BSR     PrtSTR
          
          BTST    #0,EntryMod(A4)
          BEQ.S   PRTMSGC1
          
          ; Werte v. Bus-/Addr-Error anzeigen
          MOVE.L  ErrAdr(A4),D0
          BSR     PrtLONG
          LEA     SSRMSG(PC),A1
          BSR     PrtSTR
          MOVE.W  SupSR(A4),D0
          BSR     PrtWORD
          LEA     EBFMSG(PC),A1
          BSR     PrtSTR
          MOVE.W  ErrBef(A4),D0
          BSR     PrtWORD
          
!PRTMSGC1 BTST    #1,EntryMod(A4)
          BEQ.S   PRTMSGC2
          
          ; Entry-Nummer anzeigen
          MOVE.W  EntryNr(A4),D0
          BSR     PrtBYTE
          
!PRTMSGC2 ;BTST    #0,TrcStat(A4)
          ;BNE     PRTMSGC4
          RTS
          
(*
!PRTMSGC4 BSR     PrtSPC
          MOVEQ   #'/',D0
          BSR     Prt
          BSR     PrtSPC
*)
;                                PRT TRACE MODUS (TRACE ON/OFF)
!PRTTRMOD LEA     TRMMSG(PC),A1
          BSR     PrtSTR
          BTST    #0,TrcStat(A4)
          BEQ.S   PRTTRMC1
          LEA     AKTMSG(PC),A1
          BRA.S   PRTTRMC2
!PRTTRMC1 LEA     NAKTMSG(PC),A1
!PRTTRMC2 BRA     PrtSTR


;*** REGISTER AUSGEBEN:PC,SP UND ENTRY

!PRTREGMI BSR     PrtMSG
          BSR     PrtPRMPT
          MOVEQ   #'R',D0         ; PROMPT F. REGISTER - ANZEIGE
          BSR     Prt
          MOVEQ   #TNRPC,D2       ; PC
          BSR     PrtREG
          MOVEQ   #TNRUSP,D2      ; USP
          BSR     PrtREG
          MOVEQ   #TNRSSP,D2      ; SSP
          BSR     PrtREG
          BSR     PrtSPC

!PRTSRBIN CLR.W   D2              ; SR BINAER ANZEIGEN
          LEA     SRTAB(PC),A1
!PRTSRBL2 BSR     PrtSPC
          MOVE.B  0(A1,D2.W),D1   ; STATUS - FLAG; =0,WENN ENDE D. TABELLE
          BEQ     PRTSRBE0
          MOVE.B  D1,D0
          BSR     Prt
          MOVE.B  1(A1,D2.W),D1   ; POS. V. SR
          EXT.W   D1
          MOVE.W  RgSR(A4),D0
          LSR.W   D1,D0           ; D1-MAL RECHTSSCHIEBEN
          AND.B   2(A1,D2.W),D0   ; MASKE F. WERT
          BSR     PrtNIBL
          ADDQ.W  #3,D2
          BTST    #8,D7
          BEQ.S   PRTSRBL2
!PRTSRBE0 RTS



; EINSPRUNG ZUR CMD-EINGABE-SCHLEIFE MIT MSG.-AUSGABE

!CMDBEG   CLR.W   EntryMod(A4)
!CMDBEGOC CLR.L   D7
          BCLR    #5,TrcStat(A4)  ; TRACE-FLAG wieder an ?
          BEQ     Cmdst1          ; nein
          BSET    #7,RgSR(A4)     ; TRACE-FLAG setzen
cmdst1    MOVE.L  A1,EntryMsg(A4)
          BSR     PRTREGMI
          BRA.L   CmdStart
;                                EINSPRUNG OHNE MSG.-AUSGABE
!CMDBEGOM

!CmdStart CLR.L   D7
          ; IR-Maske setzen
          MOVE    SR,D1
          ANDI.W  #$FDFF,D1
          OR.W    IRMask(PC),D1
          MOVE    D1,SR
          
          BCLR    #5,TrcStat(A4)  ; TRACE-FLAG wieder an ?
          BEQ     Cmdst0          ; nein
          BSET    #7,RgSR(A4)     ; TRACE-FLAG setzen
cmdst0    BSR.L   ResetBPs
          BSR.L   ResetShortBPs
          BSR     MonScrn         ; Monitor-Screen an
          
;                                COMMAND - EINGABE - SCHLEIFE
!CMDLOOP
(*$ ? ExtendedKeys:
          st      LockFlag
*)
          MOVE.L  MonStackHi(A4),A7
          BSR     PrtPRMPT
          BSR.L   GETLINE
          CLR.L   D7
          SUBQ.L  #1,A6
!CMDL1    BSR.L   GETNGRKL
          BMI.S   CMDLOOP
          CMPI.B  #PROMPT,D0
          BEQ.S   CMDL1
          CMPI.B  #$20,D0
          BEQ.S   CMDL1

          LEA     CMDVEC(PC),A1
          MOVE.W  #CmdTEnd-CmdTBeg,D2
          LEA     CMDTBEG(PC),A0
!CMDL2    CMP.B   (A0)+,D0
          BEQ.S   CMDFND
          ADDQ.L  #4,A1
          DBF     D2,CMDL2
          BRA.S   ERR0

!CMDFND   BSR.L   GETNGRKL
          BSET    #11,D7
          JSR     (A1)
          BRA.L   CMDLOOP
;
!ERR0     CLR.L   D6

!PRINTERR CLR.L   D7
          TST.W   RWhandle(A4)       ; War Load oder Save aktiv ?
          BEQ     PrtErrC0
          BSR.L   LSCloseErr    ; Ja : File schliessen
          BRA     PrtErrC1
PrtErrC0  BSR     PrtCRLF
PrtErrC1  LEA     ERRMSG(PC),A1
          BSR     PrtSTR
          MOVE.B  D6,D0
          LEA     ErrorList(PC),A1
          BRA     PrtErrC2
PrtErrL0  TST.B   (A1)+
          BEQ     PrtErrE0
PrtErrL1  TST.B   (A1)+
          BNE     PrtErrL1
PrtErrC2  DBRA    D6,PrtErrL0
PrtErrE0  BSR     PrtStr
          BRA.L   CMDstart
;
!ERRFF    MOVEQ   #$FF,D6
          BRA     PrintErr
!ERR1     MOVEQ   #1,D6
          BRA     PrintErr
!ERR2     MOVEQ   #2,D6
          BRA     PrintErr
!ERR3     MOVEQ   #3,D6
          BRA     PrintErr
!ERR4     MOVEQ   #4,D6
          BRA     PrintErr
!ERR5     MOVEQ   #5,D6
          BRA     PrintErr
!ERR6     MOVEQ   #6,D6
          BRA     PrintErr
!ERR7     MOVEQ   #7,D6
          BRA     PrintErr
!ERR8     MOVEQ   #8,D6
          BRA     PrintErr
!ERR9     MOVEQ   #9,D6
          BRA     PrintErr
!ERR10    MOVEQ   #10,D6
          BRA     PrintErr
!ERR11    MOVEQ   #11,D6
          BRA     PrintErr

!MONBE    BSR.L   PULLEADR        ; HOLE ERROR - ADRESSE V. STACK
          MOVEQ   #12,D6
          BRA     PrintErr

!MONAE    BSR.L   PULLEADR        ; HOLE ERROR - ADRESSE V. STACK
          MOVEQ   #13,D6
          BRA     PrintErr

!ERR14    MOVEQ   #14,D6
          BRA     PrintErr

!ERR15    MOVEQ   #15,D6
          BRA     PrintErr

!ERR16    MOVEQ   #16,D6          ; : Illegal register
          BRA     PrintErr

!ERR17    MOVEQ   #17,D6          ; : too many param.
          BRA     PrintErr

!ERR18    MOVEQ   #18,D6          ; : internal err #1
          BRA     PrintErr
;
!PULLEADR MOVEA.L (A7)+,A0        ; HOLE RTS-ADRESSE V. STACK

          TST     StkFrm
          BEQ     noFrame2
          
          ; *** BUS/ADR-Error bei 68020 behandeln ***
          MOVE.W  (A7)+,D5        ; HOLE SR V. STACK
          MOVEA.L (A7)+,A5        ; HOLE PC
          MOVE.W  (A7)+,D0        ; Hole Stack-Frame
          MOVE.L  8(A7),D1        ; ADRESSE,AUF DIE ILLEGAL ZUGEGRIFFEN WURDE
          MOVE.W  2(A7),D6        ; HOLE SUPER-STATUS-WORT V. STACK
          BMI     takePipeC       ; Fehler war in Pipe C?
          MOVE.W  6(A7),D4        ; HOLE AUSGEFšHRTEN BEFEHLS-CODE
          BRA     wasPipeB
takePipeC MOVE.W  4(A7),D4        ; HOLE AUSGEFšHRTEN BEFEHLS-CODE
wasPipeB  ; Stack-Rest bei 68020 abr„umen
          MOVE    D0,D2
          ROL     #5,D0
          ANDI    #$1E,D0
          LEA     SFTbl(PC),A1
          ADDA.W  0(A1,D0.W),A7
          MOVE.W  0(A1,D0.W),D0
          JMP     (A0)            ; RTS

noFrame2  ; *** BUS/ADR-Error bei 68000 behandeln ***
          MOVE.W  (A7)+,D6        ; HOLE SUPER-STATUS-WORT V. STACK
          ANDI.W  #$1F,D6
          MOVE.L  (A7)+,D1        ; ADRESSE,AUF DIE ILLEGAL ZUGEGRIFFEN WURDE
          MOVE.W  (A7)+,D4        ; HOLE AUSGEFšHRTEN BEFEHLS-CODE
          MOVE.W  (A7)+,D5        ; HOLE SR V. STACK
          MOVEA.L (A7)+,A5        ; HOLE PC
          JMP     (A0)            ; RTS
;
; Warteschleife bei 68020
;
DelayIf20 TST     is20(A4)
          BEQ     noDelay
          MOVE.L  DumpDelay(PC),D0
          BRA     delay2
delay1    SWAP    D0
delay2    NOP
          DBRA    D0,delay2
          SWAP    D0
          DBRA    D0,delay1
noDelay   RTS
;
;
;
!InitKeyBuf
          MOVEM.L D0/A0,-(SP)
          LEA     KEYBUF(A4),A0
          MOVE.B  #PROMPT,(A0)+
          MOVE.W  #79,D0
InitKeyBufLoop
          MOVE.B  #SPC,(A0)+
          DBRA    D0,InitKeyBufLoop
          MOVEM.L (SP)+,D0/A0
          RTS


; Inhalt des Keyboard Puffers an aktuelle Zeile ausgeben
; Inklusive Prompt-Zeichen zum Beginn der Zeile
;
DispKeyBuf
          MOVEM.L D0-D6/A0-A2,-(SP)
          MOVE.W  CursorX(A4),-(SP)
          CLR.W   CursorX(A4)
          CLR.L   D1
          LEA     KEYBUF(A4),A2
          MOVE.W  #79,D6
DispKeyBufLoop
          MOVE.W  D6,CursorX(A4)
          MOVE.B  0(A2,D6.w),D0
          BSR     ScrnOutput
          DBRA    D6,DispKeyBufLoop
          MOVE.W  (SP)+,CursorX(A4)
          MOVEM.L (SP)+,D0-D6/A0-A2
          RTS

          
!GETLINE  MOVE.W  PrHandle(A4),-(A7)
          CLR.W   PrHandle(A4)
          BSR     InitKeyBuf
          BSR     CURSORON
          LEA     KEYBUF(A4),A6
          MOVE.B  #PROMPT,(A6)+
!GETLN2   MOVEA.L A6,A5
!GETLN1   BSR.L   WAITKEY
          CMPI.B  #ESCKey,D0
          BEQ.L   GETLNESC
          CMPI.B  #CR,D0
          BEQ.L   GETLNEND
          CMPI.B  #BSKey,D0
          BEQ.L   GETLNBSP
          CMPI.B  #DelKey,D0
          BEQ.L   GETLNDEL
          CMPI.B  #InsKey,D0
          BEQ.L   GETLNINS
          CMPI.B  #CurLKey,D0
          BEQ.L   GETLNLE
          CMPI.B  #HomeKey,D0
          BEQ.L   GETLNHOMEKEY
          CMPI.B  #EndKey,D0
          BEQ.L   GETLNENDKEY
          CMPI.B  #WordLKey,D0
          BEQ.L   SearchLastWord
          CMPI.B  #WordRKey,D0
          BEQ.L   SearchNextWord
          CMPI.B  #WordHome,D0
          BEQ.L   SearchWordStart
          CMPI.B  #WordEnd,D0
          BEQ.L   SearchWordEnd
          MOVE    CursorX(A4),D1
          ADDQ    #1,D1
          CMP.W   Rows(A4),D1
          BCC     GETLN1
          CMPI.B  #CurRKey,D0
          BEQ.L   GETLNRTP
          CMPI.B  #SPC,D0
          BCS.S   GETLN1
          TST.W   EditModus(A4)
          BPL     OverwriteChar
          MOVE.W  D0,-(SP)
          BSR.L   GETINSPROC
          MOVE.W  (SP)+,D0
OverwriteChar
          MOVE.B  D0,(A6)+
!GETLN3   BSR     Prt
          CMPA.L  A5,A6
          BHI     GETLN2
          BRA     GETLN1

!GETLNEND BSR.L   InsertHistory
          LEA     KEYBUF(A4),A6
          ADDA.W  #79,A6
GETLNEND1 CMPI.B  #SPC,-(A6)
          BEQ.S   GETLNEND1
          CMPI.B  #0,(A6)
          BEQ.S   GETLNEND1
          ADDQ.L  #1,A6
          MOVE.B  #CR,(A6)
          MOVE.L  A6,D0
          LEA     KEYBUF(A4),A6
          SUB.L   A6,D0
          MOVE.W  D0,CursorX(A4)
          MOVE.W  (A7)+,PrHandle(A4)
          BEQ     GETLNE2
          ST      NoScrDisp(A4)
GETLNEL   MOVE.B  (A6)+,D0
          CMPI.B  #CR,D0
          BEQ     GETLNE1
          BSR     Prt
          BRA     GETLNEL
GETLNE1   SF      NoScrDisp(A4)
          LEA     KEYBUF(A4),A6
GETLNE2   BRA.L   CURSOROFF

!GETLNLE  MOVE.W  CursorX(A4),D0
          SUBQ.W  #1,D0
          BEQ     GETLN1
          MOVE.W  D0,CursorX(A4)
          SUBQ.L  #1,A6
          BRA     GETLN1

!GETLNESC
          MOVE.W  #1,CursorX(A4)
          LEA     KEYBUF(A4),A6
          ADDA.W  #1,A6
          MOVEA.L A6,A5
          BSR     InitKeyBuf
          BSR     DispKeyBuf
          CLR.L   D0
          BRA     GETLN1

!GETLNBSP LEA     KEYBUF(A4),A0
          CMPA.L  A0,A6
          BLE     GETLN1
          MOVE.W  CursorX(A4),D0
          SUBQ    #1,D0
          BEQ     GETLN1
          MOVE.W  D0,CursorX(A4)
          SUBA.W  #1,A6
          SUBA.W  #1,A5
          MOVE.W  CursorX(A4),D0
          MOVE.W  #79,D0
          SUB.W   CursorX(A4),D0
          ADDA.W  CursorX(A4),A0
GETLNBSPLOOP
          MOVE.B  1(A0),(A0)+
          DBRA    D0,GETLNBSPLOOP
          BSR     DispKeyBuf
          BRA     GETLN1

!GETLNDEL LEA     KEYBUF(A4),A0
          CMPA.L  A0,A6
          BLT     GETLN1
          SUBA.W  #1,A5
          MOVE.L  A0,A1
          ADDA.W  CursorX(A4),A1
          CMPA.L  A1,A5
          BGE     GETLNDELOK
          MOVE.L  A1,A5
GETLNDELOK
          MOVE.W  #79,D0
          SUB.W   CursorX(A4),D0
          ADDA.W  CursorX(A4),A0
GETLNDELPLOOP
          MOVE.B  1(A0),(A0)+
          DBRA    D0,GETLNDELPLOOP
          BSR     DispKeyBuf
          BRA     GETLN1

!GETLNINS
          TST.W   EditModus(A4)
          BEQ     SwitchIns0
          BMI     SwitchIns1
          BSR     GETINSPROC
          BRA     GETLN1
SwitchIns0
          MOVE.W  #$FFFF,EditModus(A4)
          BRA     GETLN1
SwitchIns1
          CLR.W   EditModus(A4)
          BRA     GETLN1

!GETINSPROC
          LEA     KEYBUF(A4),A0
          CMPA.L  A0,A6
          BLT     GETLN1
          ADDA.W  #1,A5
          MOVE.W  #78,D0
          SUB.W   CursorX(A4),D0
          ADDA.W  #80,A0
GETLNINSPLOOP
          MOVE.B  -2(A0),-(A0)
          DBRA    D0,GETLNINSPLOOP
          MOVE.B  #SPC,-(A0)
          BRA     DispKeyBuf


!GETLNHOMEKEY
          MOVE.W  #1,CursorX(A4)
          LEA     KEYBUF(A4),A6
          ADDA.W  #1,A6
          BRA     GETLN1

; N„chstes Wort suchen (A5 muss auf Eingabeende zeigen!)
;
SearchNextWord
          LEA     KEYBUF(A4),A0
          ADDA.W  CursorX(A4),A0
          CMPI.B  #SPC,(A0)
          BEQ     SearchNextWord2
SearchNextWord1
          CMPA.L  A5,A0
          BGE     SearchNextWordE
          CMPI.B  #SPC,(A0)+
          BNE     SearchNextWord1
SearchNextWord2
          CMPA.L  A5,A0
          BGE     SearchNextWordE
          CMPI.B  #SPC,(A0)+
          BEQ     SearchNextWord2
          SUBA.W  #1,A0
SearchNextWordE
          MOVE.L  A0,A6
          LEA     KEYBUF(A4),A0
          MOVE.L  A6,D0
          SUB.L   A0,D0
          MOVE.W  D0,CursorX(A4)
          BRA     GETLN1

; Letztes Wort suchen (A5 muss auf Eingabeende zeigen!)
;
SearchLastWord
          CMPI.W  #1,CursorX(A4)
          BEQ     SearchLastWordA
          LEA     KEYBUF(A4),A0
          MOVE.L  A0,A1
          ADDA.W  #1,A1
          ADDA.W  CursorX(A4),A0
          CMPI.B  #SPC,-1(A0)
          BEQ     SearchLastWord2
          CMPI.B  #SPC,(A0)
          BNE     SearchLastWord1
          SUBA.W  #1,A0
SearchLastWord1
          CMPA.L  A1,A0
          BLE     SearchLastWordE
          CMPI.B  #SPC,-(A0)
          BNE     SearchLastWord1
SearchLastWord2
          CMPA.L  A1,A0
          BLE     SearchLastWordE
          CMPI.B  #SPC,-(A0)
          BEQ     SearchLastWord2
          ADDA.W  #1,A0
SearchLastWordE
          MOVE.L  A0,A6
          LEA     KEYBUF(A4),A0
          MOVE.L  A6,D0
          SUB.L   A0,D0
          MOVE.W  D0,CursorX(A4)
SearchLastWordA
          BRA     GETLN1

SearchWordEnd
          LEA     KEYBUF(A4),A0
          ADDA.W  CursorX(A4),A0
          CMPI.B  #SPC,(A0)
          BEQ     SearchWordEndA
SearchWordEnd1
          CMPA.L  A5,A0
          BGE     SearchWordEndE
          CMPI.B  #SPC,(A0)+
          BNE     SearchWordEnd1
          SUBA.W  #1,A0
SearchWordEndE
          MOVE.L  A0,A6
          LEA     KEYBUF(A4),A0
          MOVE.L  A6,D0
          SUB.L   A0,D0
          MOVE.W  D0,CursorX(A4)
SearchWordEndA
          BRA     GETLN1


SearchWordStart
          LEA     KEYBUF(A4),A0
          MOVE.L  A0,A1
          ADDA.W  #1,A1
          ADDA.W  CursorX(A4),A0
          CMPI.B  #SPC,(A0)
          BNE     SearchWordStart1
          CMPI.B  #SPC,-1(A0)
          BEQ     SearchWordStartA
SearchWordStart1
          CMPA.L  A1,A0
          BLE     SearchWordStartE
          CMPI.B  #SPC,-(A0)
          BNE     SearchWordStart1
          ADDA.W  #1,A0
SearchWordStartE
          MOVE.L  A0,A6
          LEA     KEYBUF(A4),A0
          MOVE.L  A6,D0
          SUB.L   A0,D0
          MOVE.W  D0,CursorX(A4)
SearchWordStartA
          BRA     GETLN1

!GETLNENDKEY
          LEA     KEYBUF(A4),A6
          MOVE.L  A5,D0
          SUB.L   A6,D0
          MOVE.L  A5,A6
          MOVE.W  D0,CursorX(A4)
          BRA     GETLN1

!GETLNRTP CMPA.L  A5,A6
          BEQ     GETLN1
          MOVE.B  (A6)+,D0
          BRA     GETLN3
;
!GETKEY                         ; Holt Zeichen von Tastatur, wenn kein Zeichen
                                ; ansteht, wird D0.W = 0
          
          BSR     CONSTAT
          TST.L   D0
          BEQ.L   GETKEYE1
          BSR     DIRCONIN
          SWAP    D0
          CMPI.B  #$3B,D0       ; F1 ?
          BNE     GETKEYC0
          
          BSR     MonScrn       ; Monitor-Screen einschalten
          BSR     ScrnCurOn
          MOVEQ   #0,D0
          
GETKEYC0  CMPI.B  #$3C,D0       ; F2 ?
          BNE     GETKEYC1
          
          BSR     ScrnCurOff
          BSR     NormScrn      ; Monitor-Screen ausschalten
          MOVEQ   #0,D0
       
GETKEYC1  CMPI.B  #$4B,D0       ; Cursor left?
          BNE     GETKEYC11

          BSR     KbShift
          ANDI.B  #$f,D0
          BEQ     MoveLeft

          MOVEQ   #HomeKey,D0
          RTS
MoveLeft
          MOVEQ   #CurLKey,D0
          RTS
          
GETKEYC11 CMPI.B  #$73,D0       ; CNTRL Cursor Left?
          BNE     GETKEYC2

          BSR     KbShift
          ANDI.B  #$3,D0
          BEQ     CLeft
          MOVEQ   #WordHome,D0
          RTS
CLEFT
          MOVEQ   #WordLKey,D0
          RTS

GETKEYC2  CMPI.B  #$4D,D0       ; Cursor right?
          BNE     GETKEYC22
          
          BSR     KbShift
          ANDI.B  #$f,D0
          BEQ     MoveRight

          MOVEQ   #EndKey,D0
          RTS
MoveRight
          MOVEQ   #CurRKey,D0
          RTS

GETKEYC22 CMPI.B  #$74,D0       ; CNTRL Cursor right?
          BNE     GETKEYC3

          BSR     KbShift
          ANDI.B  #$3,D0
          BEQ     CRight
          MOVEQ   #WordEnd,D0
          RTS
CRight
          MOVEQ   #WordRKey,D0
          RTS

GETKEYC3  CMPI.B  #$47,D0       ; CLR HOME ?
          BNE     GETKEYC32

          BSR     KbShift
          ANDI.B  #$F,D0
          BNE     GETKEYC31
          MOVEQ   #HomeKey,D0
          RTS
GETKEYC31 MOVEQ   #EndKey,D0
          RTS
          
GETKEYC32 CMPI.B  #$77,D0       ; CNTRL Home?
          BNE     GETKEYC4
          
          MOVEQ   #ESCKey,D0
          RTS

GETKEYC4  CMPI.B  #$53,D0       ; Delete?
          BNE     GETKEYC5

          MOVEQ   #DelKey,D0
          RTS

GETKEYC5  CMPI.B  #$52,D0       ; Insert?
          BNE     GETKEYC6

          MOVEQ   #InsKey,D0
          RTS
          
GETKEYC6  CMPI.B  #$E,D0        ; Backspace?
          BNE     GETKEYC7
          
          MOVEQ   #8,D0
          RTS

GETKEYC7  CMPI.B  #$48,D0       ; Cursor Up?
          BNE     GETKEYC8
          
          BSR.L   SearchLastHistory
          MOVEQ   #0,D0
          
GETKEYC8  CMPI.B  #$50,D0       ; Cursor Down?
          BNE     GETKEYE0
          
          BSR.L   SearchNextHistory
          MOVEQ   #0,D0

GETKEYE0  SWAP    D0
          TST.W   D0
GETKEYE1  RTS
;
!WAITKEY  BSR     CursorOn
!WAITKEYL BSR     CursorBlink
          BSR     GETKEY
          BEQ     WAITKEYL
          BRA     CursorOff
;
!TSTKEY   BSR     GETKEY
          BEQ.S   TSTKEYE
          CMPI.B  #SPC,D0
          BNE.S   TSTKEYE         ; ENDE,WENN TASTE GEDRšCKT,UNGLEICH SPACE
          BSR     WAITKEY         ; BEI SPACE WARTEN AUF NEUE TASTE
          CMPI.B  #SPC,D0
!TSTKEYE  RTS

;
; History Funktionen
;

!InitHistory
          MOVEM.L A0/A1,-(SP)
          MOVE.L  HistoryStart(PC),A0
          MOVE.L  HistoryEnde(PC),A1
InitHistoryLoop
          MOVE.B  #SPC,(A0)+
          CMPA.L  A1,A0
          BCS     InitHistoryLoop
          MOVEM.L (SP)+,A0/A1
          RTS

;
!InsertHistory
          MOVE.L  HistoryEnde(PC),A0
          SUBA.L  HistoryStart(PC),A0
          CMPA.W  #80,A0
          BLT     InsertHistoryAbort
          MOVE.L  HistoryAktuell(PC),A0
          LEA     KEYBUF(A4),A1
          MOVEQ   #78,D0
InsertHistoryTest
          TST.B   1(A1,D0.w)
          BEQ     InsertHistoryTestNext
          CMPI.B  #SPC,1(A1,D0.w)
          BEQ     InsertHistoryTestNext
          CMPI.B  #CR,1(A1,D0.w)
          BNE     InsertHistoryTest1
InsertHistoryTestNext
          DBRA    D0,InsertHistoryTest
          BRA     InsertHistoryAbort
InsertHistoryTest1
          CMP.B   edit_minimum(PC),D0
          BLS     InsertHistoryAbort
          LEA     KEYBUF(A4),A1
          MOVEQ   #19,D0
InsertHistoryLoop
          MOVE.L  (A1)+,(A0)+
          DBRA    D0,InsertHistoryLoop
          CMPA.L  HistoryEnde(PC),A0
          BLT     InsertHistoryEnde
          MOVE.L  HistoryStart(PC),A0
InsertHistoryEnde
          MOVE.L  A0,D0
          LEA     HistoryAktuell(PC),A0
          MOVE.L  D0,(A0)
          LEA     HistorySuchen(PC),A0
          MOVE.L  D0,(A0)
          LEA     HistoryFill(PC),A0
          MOVE.L  (A0),D0
          CMP.L   HistoryEnde(PC),D0
          BGE     InsertHistoryAbort
          ADD.L   #80,D0
          MOVE.L  D0,(A0)
InsertHistoryAbort
          RTS

;
!CopyFromHistory
          MOVE.L  HistoryFill(PC),A0
          SUBA.L  HistoryStart(PC),A0
          CMPA.W  #80,A0
          BLT     CopyFromHistoryAbort
          MOVE.L  HistorySuchen(PC),A0
          LEA     KEYBUF(A4),A1
          MOVEQ   #19,D0
CopyFromHistoryLoop
          MOVE.L  (A0)+,(A1)+
          DBRA    D0,CopyFromHistoryLoop
CopyFromHistoryAbort
          RTS
;
!SearchNextHistory
          MOVE.L  HistoryStart(PC),D0
          CMP.L   HistoryFill(PC),D0      ; Ist �berhaupt schon was drin?
          BEQ     SearchNextHistoryAbort
          MOVE.L  HistorySuchen(PC),A0
          ADDA.W  #80,A0
          CMPA.L  HistoryFill(PC),A0      ; Obere Wassermarke erreicht?
          BLT     SearchNextHisTest
          MOVE.L  HistoryStart(PC),A0
!SearchNextHisTest
          MOVE.L  A0,D0
          LEA     HistorySuchen(PC),A1
          MOVE.L  D0,(A1)
          BSR     CopyFromHistory
          BSR     AdjustBound
          BRA     DispKeyBuf
SearchNextHistoryAbort
          RTS
;
SearchLastHistory
          MOVE.L  HistoryStart(PC),D0
          CMP.L   HistoryFill(PC),D0      ; Ist �berhaupt schon was drin?
          BEQ     SearchLastHistoryAbort
          MOVE.L  HistorySuchen(PC),A0
          SUBA.W  #80,A0
          CMPA.L  HistoryStart(PC),A0     ; untere Wassermarke erreicht?
          BGE     SearchLastHisTest
          MOVE.L  HistoryFill(PC),A0
          SUBA.L  #80,A0
SearchLastHisTest
          MOVE.L  A0,D0
          LEA     HistorySuchen(PC),A1
          MOVE.L  D0,(A1)
          BSR     CopyFromHistory
          BSR     AdjustBound
          BRA     DispKeyBuf
SearchLastHistoryAbort
          RTS
;
AdjustBound
          LEA     KEYBUF(A4),A0
          MOVE.W  #79,D0
AdjustBoundLoop                           ; Ende der Zeile suchen
          CMPI.B  #SPC,0(A0,D0.w)
          BNE     AdjustBound1
          DBRA    D0,AdjustBoundLoop
AdjustBound1
          ADDQ.W  #1,D0                   ; Vergleich mit aktueller Cursorpos.
          ADDA.W  D0,A0
          MOVE.W  D0,CursorX(A4)
          MOVE.L  A0,A6
          MOVE.L  A0,A5
          RTS
;
SetMonVec MOVE.L  BUSERRV,RgBEV(A4)   ; RETTE BUS-ERROR-VECTOR
          MOVE.L  ADRERRV,RGAEV(A4)   ; RETTE ADRESS-ERROR-VECTOR
          TST.W   is20(A4)
          BNE     is20_1
          CLR.B   RgBEV(A4)
          CLR.B   RgAEV(A4)
is20_1    LEA     MONBE(PC),A5
          MOVE.L  A5,BUSERRV          ; BUS-ERROR VECTOR AUF MON-ERROR-AUSGABE
          LEA     MONAE(PC),A5
          MOVE.L  A5,ADRERRV          ; ADR-ERROR VECTOR AUF MON-ERROR-AUSGABE
          RTS

!SetMon   ; D7 muž erhalten bleiben
          ; Register A1 nicht veraendern !
          MOVE    SR,-(A7)
          MOVE    #$2700,SR
          BSR     SetMonVec
          LEA     EyCritic(PC),A5
          MOVE.L  etv_critic,-4(A5)
          MOVE.L  A5,etv_critic
(*$? ADC:
          LEA     OldMiKey(PC),A1                 ; alte Keyb.R. speichern.
          MOVE.L  MidiKeyV,(A1)
          LEA     NKeyMidi(PC),A1                 ; Neue Routine holen
          MOVE.L  A1,MidiKeyV                     ; und setzen
*)
          MOVE    (A7)+,SR
          RTS
;
;
!ResetMon ORI     #$0700,SR
          SF      MonActive
(*$? ADC:
          MOVE.L  OldMiKey(PC),MidiKeyV           ; auf alte Keyb.R. umschal.
*)
          LEA     EyCritic(PC),A0
          MOVE.L  -4(A0),etv_critic

RstMonVec MOVE.L  RgBEV(A4),BUSERRV   ; HOLE BUS-ERROR-VECTOR ZURšCK
          MOVE.L  RgAEV(A4),ADRERRV   ; HOLE ADRESS-ERROR-VECTOR ZURšCK
          RTS
;
;
!CAPS     CMPI.B  #'z',D0
          BHI     NOTKL
          CMPI.B  #'a',D0
          BCS     NOTKL
          SUBI.B  #$20,D0
!NOTKL    RTS
;
!GETNGRKL ADDQ.L  #1,A6
!GETLGRKL MOVE.B  (A6),D0
          BSR     CAPS
          CMPI.B  #CR,D0
          BNE.S   GETGKRET
          BSET    #15,D7
!GETGKRET TST.W   D7
          RTS
;
!TSTHZIFF CMPI.B  #'0',D0
          BCS.S   TSTHZER
          CMPI.B  #'9',D0
          BLS.S   TSTHZOK
          CMPI.B  #'A',D0
          BCS.S   TSTHZER
          CMPI.B  #'F',D0
          BHI.S   TSTHZER
          SUBI.B  #7,D0
!TSTHZOK  SUBI.B  #'0',D0
          ORI     #ZERO,CCR
          RTS
!TSTHZER  ANDI    #NEGZERO,CCR
          RTS
;
!TSTADR   CMPI.B  #OFFSCHAR,D0
          BEQ.S   TSTADRE
          CMPI.B  #'&',D0
          BEQ.S   TSTADRE
          CMPI.B  #'R',D0
          BEQ.S   TSTADRE
          CMPI.B  #'P',D0
          BEQ.S   TSTADRE
          CMPI.B  #'(',D0
          BEQ.S   TSTADRE
          BSR.L   TSTHZIFF
          BNE.S   TSTADRE
          BSR.L   GETLGRKL
          ORI     #ZERO,CCR
!TSTADRE  RTS
;
!GETLONGX MOVE.L  #$FFFFFFF,D6
          BRA.W   GetExpr0

!GETLONGO MOVE.L  #$FFFFFFF,D6
          BRA.W   GetExprU

!GETLONG  MOVE.L  #$FFFFFFF,D6
          BRA.W   GETADR2

!GETWORD  MOVE.L  #$FFF,D6
          BRA.W   GETADR2

!GETBYTE  MOVE.L  #$F,D6
          BRA.W   GETADR2

!GETADRG  BSR.S   GETADR0         ; GERADE ADR. HOLEN
          BTST    #12,D7
          BNE.S   GADGC1
          BCLR    #0,D1
!GADGC1   RTS

!GETADR0  BSR.L   SKIPSPC

!GETADR   CMPI.B  #'P',D0
          BNE     GETADR1
          BSR     GETNGRKL
          BSR.L   SKIPSPC
          MOVE.W  D0,-(SP)
          CMPI.B  #'(',D0
          BNE     GETADRPPARSE
          BSR     GETNGRKL
GETADRPPARSE
          BSR     GETADR0
          TST     is20(A4)      ; beim 68020 32 Bit Adresse, ungerade Adresse m”glich!
          BNE     GETADRPPARSE1
          ANDI.L  #$FFFFFE,D1
GETADRPPARSE1
          MOVE.L  A0,-(SP)
          MOVEA.L D1,A0
          MOVE.L  (A0),D1
          MOVE.L  (SP)+,A0
          MOVE.W  (SP)+,D0
          CMPI.B  #'(',D0
          BEQ     GETADRPKL
          BSR     GETLGRKL
          BRA.L   GETADRET
GETADRPKL
          BSR     GETLGRKL
          CMPI.B  #')',D0
          BNE.L   GETADRET
          BSR     GETNGRKL
          BSR.L   SKIPSPC
          CMPI.B  #'+',D0
          BEQ     GETADRPPL
          CMPI.B  #'-',D0
          BNE.L   GETADRET
GETADRPMI BSR     GETNGRKL
          MOVE.L  D1,-(SP)
          BSR     GETADR0
          SUB.L   D1,(SP)
          MOVE.L  (SP)+,D1
          BRA.L   GETADRET
GETADRPPL BSR     GETNGRKL
          MOVE.L  D1,-(SP)
          BSR     GETADR0
          ADD.L   (SP)+,D1
          BRA.L   GETADRET
          
GETADR1
          CMPI.B  #'(',D0
          BNE     GETADR12
          BSR     GETNGRKL
          BSR     GETADR0
          MOVE.L  D1,-(SP)
          BSR.L   SKIPSPC
          CMPI.B  #')',D0
          BEQ     GETADRNECH
          ADDQ.L  #4,SP
          BRA.L   GETADRET
GETADRNECH
          BSR     GETNGRKL
          BSR.L   SKIPSPC
          MOVE.W  D0,-(SP)
          MOVE.L  A6,-(SP)
          CMPI.B  #'-',D0
          BEQ     GETADRNEXT
          CMPI.B  #'+',D0
          BEQ     GETADRNEXT
          MOVE.L  (SP)+,A6
          MOVE.W  (SP)+,D0
          MOVE.L  (SP)+,D1
          BRA.L   GETADRET
GETADRNEXT
          BSR     GETNGRKL
          BSR     GETADR0
          CMPI.W  #'-',4(SP)
          BEQ     GETADRMINUS
          ADD.L   6(SP),D1
          BRA     GETADRREST
GETADRMINUS
          SUB.L   D1,6(SP)
          MOVE.L  6(SP),D1
GETADRREST
          ADDA.L  #10,SP
          CMPI.B  #')',D0
          BNE.L   GETADRET
          BSR     GETNGRKL
          BRA.L   GETADRET

GETADR12
          MOVE.L  #$FFFFFFF,D6
          TST     is20(A4)
          BNE     GetExpr0
          MOVE.L  #$FFFFF,D6
!GetExpr0 CLR.L   -(A7)
          MOVE    #1,-(A7)
          BRA.S   GexprC1
GExprL1   MOVE    D0,-(A7)
          BSR.L   GETNGRKL
GExprC1   BSR.W   GetExprU
          TST     (A7)+
          BEQ.S   GExprSub
          ADD.L   D1,(A7)
          BRA.S   GExprC0
GExprSub  SUB.L   D1,(A7)
GExprC0   CMPI.B  #'+',D0
          BEQ     GexprL1
          CMPI.B  #'-',D0
          BNE.S   GetAdRet2
          MOVEQ   #0,D0
          BRA     GexprL1
GetAdRet2 MOVE.L  (A7)+,D1
          TST.W   D7
          RTS
          
GetExprU  CMPI.B  #'(',D0
          BNE     GetExprU1
          BSR     GETADR
          BRA.L   GETADRET
GetExprU1 CMPI.B  #'P',D0
          BNE     GetExprU2
          BSR     GETADR
          BRA.L   GETADRET
GetExprU2 CMPI.B  #OFFSCHAR,D0
          BNE.W   GetAdr2
          
          BSR.L   GETNGRKL
          SF      ValExp(A4)
          BSR     GetAdr3
          ADD.L   AdOffset(A4),D1
          TST.W   D7
          RTS

!GETADR2  ST      ValExp(A4)
GetAdr3   CLR.L   D1
          CMPI.B  #'&',D0
          BEQ.S   GETDADR
          CMPI.B  #'R',D0
          BEQ.L   GETRGADR
          BSR.L   TSTHZIFF
          BEQ.S   GETADL1
          TST.B   ValExp(A4)
          BEQ.S   GETADRET
          BRA     ERR1

!GETADL1  CMP.L   D6,D1
          BHI     ERR2
          LSL.L   #4,D1
          OR.B    D0,D1
          BSR.L   GETNGRKL
          BMI.S   GETADRET
          BSR.L   TSTHZIFF
          BEQ     GETADL1

!GETADRET TST.W   D7
          RTS
;
;
!GETDADR  BSR     GETNGRKL        ; NAECHSTES ZEICHEN HOLEN
!GETDEZ   BSR     TSTHZIFF        ; HEX-ZIFFER ?
          BNE     GETADRET        ; NEIN: ENDE
          CMPI.B  #9,D0           ; DEZ.-ZIFFER ?
          BHI.S   GETADRET        ; NEIN: ENDE
          CMP.L   D6,D1           ; ZAHL ZU GROSS ?
          BHI     ERR2            ; JA: ERROR
          EXT.W   D0
          EXT.L   D0              ; D0.L = ZIFFER
                                  ; NEIN: D1 MIT 10 MULTIPLIZIEREN:
          ASL.L   #1,D1           ; D1 MAL 2
          MOVE.L  D1,-(A7)        ; D1 AUF STACK ZWISCHENSPEICHERN
          ASL.L   #2,D1           ; D1 JETZT MAL 8
          ADD.L   (A7)+,D1        ; D1 MAL 2 DAZUADDIEREN
          ADD.L   D0,D1           ; D1 JETZT MAL 10, DEZ.ZIFFER ADDIEREN
          BRA     GETDADR         ; NAECHSTE ZIFFER

!GetRgAdr MOVEM.L D2/A0-A1,-(A7)
          BSR.L   SkipSpcN
          MOVE.B  D7,-(A7)      ; Bit 15 nicht auf Stack !
          BSR.L   BerRegNr
          BTST    #2,D7
          BNE     ERR16
          BTST    #3,D7
          BNE     ERR16
          MOVE.B  (A7)+,D7
          LEA     RegBeg(A4),A0
          LSL     #2,D2
          MOVE.L  0(A0,D2.W),D1
          MOVEM.L (A7)+,D2/A0-A1
          BRA     GETADRET
;
!GETAE    BSR.L   SKIPSPC
          BMI.L   GETAEDFT
          BSR.L   TSTADR          ; ANGABE EINER ANF. ADR. ?
          BNE.L   GETADEFT        ; NEIN: DEFAULT-WERT HOLEN
          BSR.L   GETADRG
          MOVEA.L D1,A2
          BSET    #2,D7
          TST.W   D7
          BMI.L   GETAEEQU
!GETEC0   BSR.L   SKIPSPC
          CMPI.B  #'.',D0
          BEQ.S   GETEC1
          CMPI.B  #'Z',D0         ; ANGABE DER ZEILENZAHL ?
          BEQ.S   GETEZ
          CMPI.B  #'X',D0         ; ANGABE BYTE-ANZAHL ?
          BNE.S   GETEC2
          BSR.L   SkipSpcN
          BMI.S   GETEDEFT
          BSR.L   TSTADR
          BNE.S   GETEDEFT        ; DEFAULT-ENDADR.,WENN KEINE ZAHL FOLGT
          BSR.L   GETLONGX        ; JA: ANZAHL HOLEN
          ADD.L   A2,D1           ; ANF.-ADR. ADDIEREN
          BCC.S   GETEC4
          MOVEQ   #-1,D1          ; BEI šBERTRAG MAX. WERT NEHMEN
!GETEC4   BTST    #12,D7
          BNE     GetEC5
          BCLR    #0,D1           ; ENDADR. BEGRADIGEN
          BRA.S   GETEC5
!GETEC1   BSR.L   SkipSpcN
          BMI     GETEDEFT
          BSR.L   TSTADR
          BNE.S   GETEDEFT        ; DEFAULT-ENDADR.,WENN KEINE ZAHL FOLGT
!GETEC2   BSR.L   GETADRG
!GETEC5   MOVEA.L D1,A3
          BSET    #3,D7
!GETAERET CMPA.L  A3,A2
          BHI     ERR3            ; ERROR: A2>A3
!GETAERT0 MOVE.L  A2,(A1)
          TST.W   D7              ; TEST AUF CR
          BTST    #2,D7           ; ANF. ADR. ANGEGEBEN ?
          BEQ.S   GETAERT2
          BTST    #3,D7           ; END ADR. ANGEGEBEN ?
!GETAERT2 RTS                     ; N=1:CR FOLGT / Z=0: BEIDE ADR. ANGEGEBEN

!GETADEFT MOVEA.L 4(A1),A2
          BRA.L   GETEC0

!GETAEDFT MOVEA.L (A1),A2         ; LAST*A - ADR. ALS ANF. ADR.

!GETEDEFT MOVEA.L #-1,A3
          BRA.L   GETAERET

!GETAEEQU MOVEA.L A2,A3
          BRA.L   GETAERET

!GETEZ    BSR.L   SkipSpcN
!GETEZ0   BPL.S   GETEZC1
          MOVEQ   #1,D1
          BRA.S   GETEZC2
!GETEZC1  BSR.L   GETLONG
!GETEZC2  MOVE.L  D1,D3
          BSET    #1,D7           ; : ZEILENANZ. GEWAEHLT
          BRA.L   GETAERT0
;
!SKIPSPC  BSR.L   GETLGRKL
          BMI.S   SKIPEND
!SKIPSPC2 CMPI.B  #SPC,D0
          BNE.S   SKIPEND
!SKIPSPCN BSR.L   GETNGRKL
          BPL.S   SKIPSPC2
!SKIPEND  TST.W   D7
          RTS
;
;
;
!TSTNCR   BSR.L   GETNGRKL
          BPL     ERR4
          RTS
;
; MEMORY HEX-DUMP Byteweise
;
!CIU      MOVE.B  (A2)+,D0
          BSET    #13,D7          ; Controlchars als druckbare Zeichen darst.
          BSR     Prt
          DBF     D5,CIU
          RTS
;
!ComdM    CMPI.B  #'W',D0
          BEQ.L   ComdMW
          CMPI.B  #'L',D0
          BEQ.L   ComdML
          LEA     LastMA(A4),A1   ; LETZTE ANF.ADR. ALS DEFAULT-WERT-POINTER
          BSET    #12,D7          ; Ungerade Adr. erlaubt
          BSR.L   GETAE           ; ANF.-/END- ADR. NACH A2/A3 HOLEN
!CMC0     BPL     ERR4
!DUMPNXLN MOVEQ   #HDUMPANZ-1,D6  ; ANZ. bytes -1 PRO ZEILE
          BSR     PrtPRMPT
          MOVEQ   #':',D0
          BSR     Prt
          MOVE.L  A2,D0           ; PRINT ADRESSE
          BSR     PrtADR
          BSR     PrtSPC
          CLR.W   D5
!DUMPLNL1 BSR     PrtSPC
          MOVE.B  (A2)+,D0
          BSR     PrtByte
          MOVE    A2,D0  ;MOVE.B D5,D0
          ANDI.B  #11%,D0
          BNE     CmdMC1
          BSR     PrtSPC
CmdMc1    ADDQ.W  #1,D5
          BTST    #1,D7
          BNE.S   CMC1
          CMPA.L  A3,A2
          BCC.S   CMEND
!CMC1     DBRA    D6,DUMPLNL1
          
          SUBA.W  D5,A2
          MOVEQ   #ASCDUMPX,D1
          BSR     PRTMSPC
          MOVEQ   #ASCPRMPT,D0
          BSR     PRT
          SUBQ.W  #1,D5
          BSR.L   CIU
          
          BSR.L   TSTKEY
          BNE     CMEND
          ; Warteschleife f. 68020
          BSR     DelayIf20
          BTST    #1,D7
          BEQ     DUMPNXLN
          SUBQ.L  #1,D3
          BNE     DUMPNXLN
         
!CMEND    MOVE.L  A2,LastME(A4)
          RTS
;
; MEMORY HEX-DUMP Wordweise
;
!ComdMW   BSR.L   GETNGRKL
          LEA     LastMA(A4),A1   ; LETZTE ANF.ADR. ALS DEFAULT-WERT-POINTER
          BCLR    #12,D7          ; Ungerade Adr. nicht erlaubt
          BSR.L   GETAE           ; ANF.-/END- ADR. NACH A2/A3 HOLEN
!CMC0W    BPL     ERR4
!DUMPNXLNW MOVEQ   #(HDUMPANZ DIV 2)-1,D6  ; ANZ. bytes -1 PRO ZEILE
          BSR     PrtPRMPT
          MOVEQ   #':',D0
          BSR     Prt
          MOVEQ   #'w',D0
          BSR     Prt
          MOVE.L  A2,D0           ; PRINT ADRESSE
          BSR     PrtADR
          BSR     PrtSPC
          BSR     PrtSPC
          BSR     PrtSPC
          CLR.W   D5
!DUMPLNL1W
          BSR     PrtSPC
          MOVE.W  (A2)+,D0
          BSR     PrtWord
          MOVE    A2,D0  ;MOVE.B D5,D0
          ANDI.B  #11%,D0
          BNE     CmdMC1W
          BSR     PrtSPC
          BSR     PrtSPC
CmdMc1W   ADDQ.W  #2,D5
          BTST    #1,D7
          BNE.S   CMC1W
          CMPA.L  A3,A2
          BHI.S   CMENDW
!CMC1W    DBRA    D6,DUMPLNL1W
          
          SUBA.W  D5,A2
          MOVEQ   #ASCDUMPX+1,D1
          BSR     PRTMSPC
          MOVEQ   #ASCPRMPT,D0
          BSR     PRT
          SUBQ.W  #1,D5
          BSR.L   CIU
          
          BSR.L   TSTKEY
          BNE     CMENDW
          ; Warteschleife f. 68020
          BSR     DelayIf20
          BTST    #1,D7
          BEQ     DUMPNXLNW
          SUBQ.L  #1,D3
          BNE     DUMPNXLNW
         
!CMENDW   MOVE.L  A2,LastME(A4)
          RTS
;
; MEMORY HEX-DUMP LongWordweise
;
!ComdML   BSR.L   GETNGRKL
          LEA     LastMA(A4),A1   ; LETZTE ANF.ADR. ALS DEFAULT-WERT-POINTER
          BCLR    #12,D7          ; Ungerade Adr. nicht erlaubt
          BSR.L   GETAE           ; ANF.-/END- ADR. NACH A2/A3 HOLEN
!CMC0L    BPL     ERR4
!DUMPNXLNL MOVEQ   #(HDUMPANZ DIV 4)-1,D6  ; ANZ. bytes -1 PRO ZEILE
          BSR     PrtPRMPT
          MOVEQ   #':',D0
          BSR     Prt
          MOVEQ   #'l',D0
          BSR     Prt
          MOVE.L  A2,D0           ; PRINT ADRESSE
          BSR     PrtADR
          BSR     PrtSPC
          BSR     PrtSPC
          CLR.W   D5
!DUMPLNL1L
          BSR     PrtSPC
          BSR     PrtSPC
          MOVE.L  (A2)+,D0
          BSR     PrtLONG
          MOVE    A2,D0  ;MOVE.B D5,D0
;          ANDI.B  #111%,D0
;          BNE     CmdMC1L
          BSR     PrtSPC
          BSR     PrtSPC
CmdMc1L   ADDQ.W  #4,D5
          BTST    #1,D7
          BNE.S   CMC1L
          CMPA.L  A3,A2
          BHI.S   CMENDL
!CMC1L    DBRA    D6,DUMPLNL1L
          
          SUBA.W  D5,A2
          MOVEQ   #ASCDUMPX+2,D1
          BSR     PRTMSPC
          MOVEQ   #ASCPRMPT,D0
          BSR     PRT
          SUBQ.W  #1,D5
          BSR.L   CIU
          
          BSR.L   TSTKEY
          BNE     CMENDL
          ; Warteschleife f. 68020
          BSR     DelayIf20
          BTST    #1,D7
          BEQ     DUMPNXLNL
          SUBQ.L  #1,D3
          BNE     DUMPNXLNL
         
!CMENDL   MOVE.L  A2,LastME(A4)
          RTS
;
; SPEICHERBEREICHE VERSCHIEBEN / VERGLEICHEN
;
!GET3ADR  LEA     Hilf1L(A4),A1
          BSET    #12,D7          ; Ungerade Adr. erlaubt
          BSR.L   GETAE
          BEQ     ERR1
          BSR.L   GETADRG
          BPL     ERR4
          RTS                     ; ADR. IN : A2 / A3 / D1
;
!ComdC    BCLR    #11,D7
          BSR.L   GET3ADR         ;COPY
          MOVEA.L D1,A5

!CTRF     CMPA.L  A2,A5           ; TRANSFER-UPRO: (A2) - (A3) => (A5)
          BLS     CTRFUP
          
          SUBA.L  A2,A5           ; VON OBEN NACH UNTEN VERSCHIEBEN
          ADDA.L  A3,A5           ; ZIEL-END-ADR. BESTIMMEN
          ADDQ.L  #1,A5
          ADDQ.L  #1,A3
!CTRFDWN  MOVE.B  -(A3),-(A5)
          CMPA.L  A2,A3
          BCC     CTRFDWN
          RTS
          
!CTRFUP   MOVE.B  (A2)+,(A5)+     ; VON UNTEN NACH OBEN VERSCHIEBEN
          CMPA.L  A3,A2
          BCS     CTRFUP
          RTS
;
!ComdV    BCLR    #11,D7
          CMPI.B  #CR,1(A6)
          BNE     CVC0
          CMPI.B  #'I',D0
          BNE     CVC0

; VI - Vector restore
;
          BSR     RstMonVec
          MOVEQ   #1,D0              ; InitVec: Žnderungen anzeigen
          MOVEQ   #0,D1              ; InitVec: von TRAPs nur Nr 6 setzen
          BSR.L   InitVec
          BRA     SetMonVec

; V - Verify
;
CVC0      BSR.L   GET3ADR
          MOVEA.L D1,A5
          BSR     PrtCRLF
          BSR     PrtSPC
          MOVEQ   #7,D5
          
!CCMP     CMPM.B  (A2)+,(A5)+
          BNE.S   CCMPC1
!CCMPC2   CMPA.L  A3,A2
          BCS     CCMP
          RTS
          
!CCMPC1   MOVEA.L A2,A1
          SUBQ.L  #1,A1
          BSR.L   CCMPU1
          MOVEQ   #'-',D0
          BSR     Prt
          MOVEA.L A5,A1
          SUBQ.L  #1,A1
          BSR.L   CCMPU1
          CMPI.B  #1,D5
          BEQ     CCMPC3
          MOVEQ   #4,D1
          BSR     PrtMSPC
!CCMPC3   BSR.L   TSTKEY
          BEQ     CCMPC2
          RTS

!CCMPU1   SUBQ.B  #1,D5
          BNE     CCMPUC
          BSR     PrtCRLF
          BSR     PrtSPC
          MOVEQ   #6,D5
!CCMPUC   MOVE.L  A1,D0
          BSR     PrtADR
          MOVEQ   #':',D0
          BSR     Prt
          MOVE.B  (A1),D0
          BRA     PrtByte
;
; BREAKPOINT SETZEN / ANZEIGEN
;
!USERBRKP BSR.L   GETNGRKL
          BMI.S   SHOWUSR
          BSR.L   GETADRG
          BPL     ERR4
          MOVE.L  D1,UsrBPV

!SHOWUSR  BSR     PRTPRMPT
          MOVEQ   #'B',D0
          BSR     PRT
          MOVEQ   #'U',D0
          BSR     PRT
          BSR     PRTSPC
          MOVE.L  UsrBPV,D0
          BRA     PRTADR
;
!CBPCLR   BSR.L   TSTNCR
ClrBPs    LEA     BP(A4),A1
          MOVEQ   #BPanz+BPanz-1,D0
!CBPCLRL  CLR.L   (A1)+
          DBF     D0,CBPCLRL
          BCLR    #11,D7
          SF      BPset(A4)
          RTS
;
!ComdB    LEA     BP(A4),A1
          
          BSR.L   SKIPSPC
          BMI.L   SHOWBP0
          
          CMPI.B  #'U',D0
          BEQ     USERBRKP
          
          CMPI.B  #'-',D0
          BEQ     CBPCLR
          
          BSR.L   TSTHZIFF
          BNE     ERR1
          CMPI.B  #BPanz-1,D0
          BHI     ERR2
          MOVE.B  D0,D5
          EXT.W   D5
          MOVE    D5,D4
          ASL.B   #2,D4
          BSR.L   GETNGRKL
          BMI     SHOWBRKP
          CMPI.B  #SPC,D0
          BNE     Err6
          BSR     SkipSpcN
          MOVEQ   #1,D0
          MOVEA.W D0,A2
          MOVEA.W D0,A3
          BCLR    #12,D7          ; nur gerade Adr.
          BSR.L   GETADRG
          MOVE.L  D1,0(A1,D4.W)
          BNE     CBPC1
          MOVEA.W D1,A2
          MOVEA.W D1,A3
          BRA     CBPE1
!CBPC1    TST.W   D7
          BMI.S   CBPE1
          BSR.L   SKIPSPC
          BSR.L   GETWORD
          MOVEA.W D1,A2
          BPL.S   CBPC2
          MOVEA.W D1,A3
          BRA.S   CBPE1
!CBPC2    BSR.L   SKIPSPC
          BSR.L   GETWORD
          MOVEA.W D1,A3
!CBPE1    MOVE.W  A2,BPanz+BPanz+BPanz+BPanz(A1,D4.W)     ; BPC
          MOVE.W  A3,BPanz+BPanz+BPanz+BPanz+2(A1,D4.W)   ; BPCA
          
          ; Testen, ob irgendein BP gesetzt ist
          LEA     BP(A4),A0
          MOVEQ   #BPanz-1,D0
!CBPCLRL2 TST.L   (A0)+
          DBNE    D0,CBPCLRL2
          SNE     BPset(A4)
          
!SHOWBRKP BSR     PrtPRMPT
          MOVEQ   #'B',D0
          BSR     Prt
          MOVE.B  D5,D0
          BSR     PrtNIBL
          BSR     PrtSPC
          MOVE.W  D5,D4
          LSL.W   #2,D4
          MOVE.L  0(A1,D4.W),D0
          BSR     PrtADR
          BSR     PrtSPC
          MOVE.W  BPanz+BPanz+BPanz+BPanz(A1,D4.W),D0    ;BPC
          BSR     PrtWORD
          BSR     PrtSPC
          MOVE.W  BPanz+BPanz+BPanz+BPanz+2(A1,D4.W),D0  ;BPCA
          BRA     PrtWORD

!SHOWBP0  CLR.L   D5
          TST     BPset(A4)
          BEQ     noBPset
!SHOWBPL  MOVE.W  D5,D4
          LSL.W   #2,D4
          TST.L   0(A1,D4.W)
          BEQ     BPnotSet
          BSR.S   SHOWBRKP
BPnotSet  ADDQ.B  #1,D5
          CMPI.B  #BPanz,D5
          BCS.S   SHOWBPL
          RTS
noBPSet   LEA     noBPsMsg(PC),A1
          BCLR    #11,D7
          BRA     PrtStr
;
!ComdO    BMI.S   SHOWOFFS
          BSR.L   GETADR0
          BPL     ERR4
          MOVE.L  D1,AdOffset(A4)

!SHOWOFFS BSR     PrtPrmpt
          MOVEQ   #'O',D0
          BSR     Prt
          BSR     PrtSPC
          MOVE.L  AdOffset(A4),D0
          BRA     PrtADR
;
; Alle cmds anzeigen
;
PrComds   LEA     CmdCmt(PC),A1
          BSR     PrtCRLF
PrCmdL1   MOVEQ   #23,D2
PrCmdL0   BSR     PrtStr
          BSR     TstKey
          BNE     PrCmdE0
          TST.B   (A1)
          BEQ     PrCmdE0
          BSR     PrtCRLF
          DBRA    D2,PrCmdL0
          MOVE.L  A1,-(A7)
          MOVE.W  PrHandle(A4),-(A7)
          CLR.W   PrHandle(A4)
          LEA     PressKeyMsg(PC),A1
          BSR     PrtStr
          BSR     WaitKey
          MOVE    D0,D1
          BSR     PrtCRLF
          MOVE.W  (A7)+,PrHandle(A4)
          MOVE.L  (A7)+,A1
          CMPI.B  #' ',D1
          BEQ     PrCmdL1
PrCmdE0   RTS
;
; Rechnen
;
!ComdFRAG BMI     PRCOMDS
          BCLR    #11,D7
          BSR     SKIPSPC
          BSR     GETLONGO
          BMI     ERR15
          MOVE.L  D1,-(A7)
          BSR     SKIPSPC
          MOVE.B  D0,D2
          BSR     GETNGRKL
          BMI     ERR1
          BSR     SKIPSPC
          BSR     GETLONGO
          BPL     ERR4
          BSR     PRTSPC
          MOVEQ   #'=',D0
          BSR     PRT
          BSR     PRTSPC
          MOVE.L  (A7)+,D0
          CMPI.B  #'+',D2
          BEQ     CFPLUS
          CMPI.B  #'-',D2
          BEQ     CFMINUS
          CMPI.B  #'*',D2
          BEQ     CFMULT
          CMPI.B  #'/',D2
          BEQ     CFDIV
          CMPI.B  #'E',D2
          BEQ     CFEOR
          CMPI.B  #'O',D2
          BEQ     CFOR
          CMPI.B  #'A',D2
          BNE     ERR14
!CFAND    AND.L   D1,D0
          BRA     PrtLONG
          
!CFMINUS  SUB.L   D1,D0
          BRA.S   CFPLMI

!CFPLUS   ADD.L   D1,D0
!CFPLMI   MOVE    SR,-(A7)
          BSR     PrtLONG
          LEA     CFLMSG(PC),A1
          BSR     PrtSTR
          MOVE    (A7)+,D0
          ANDI.B  #1,D0
          BRA     PrtNIBL

!CFMULT   MULU    D1,D0
          BRA     PrtLONG
          
!CFDIV    TST.W   D1
          BEQ     ERR14           ; ERROR: DIV DURCH NULL
          DIVU    D1,D0
          MOVE.L  D0,-(A7)
          BSR     PrtWORD
          LEA     RMDMSG(PC),A1
          BSR     PrtSTR
          MOVE.L  (A7)+,D0
          SWAP    D0
          BRA     PrtWORD

!CFEOR    EOR.L   D1,D0
          BRA     PrtLONG
          
!CFOR     OR.L    D1,D0
          BRA     PrtLONG
;
;
!ComdR    BMI.L   CRC5
          CMPI.B  #'-',D0
          BNE.L   CRC1
          
          ; Entry-Msg und Modulposition ausgeben
          
          BSR.L   TSTNCR
          
          BRA     PrtMSG
          
CRC4      BCLR    #11,D7
          CMPI.B  #'S',D0
          BNE     CRC6
          
          ; 'RS' - Reg save
          MOVEQ   #19,D0
          LEA     RegBeg(A4),A0
          LEA     Regsave(A4),A1
CRL4      MOVE.L  (A0)+,(A1)+
          DBRA    D0,CRL4
          RTS

CRC6      CMPI.B  #'R',D0
          BNE     Err0
          
          ; 'RR' - Reg restore
          MOVEQ   #19,D0
          LEA     RegBeg(A4),A1
          LEA     Regsave(A4),A0
CRL5      MOVE.L  (A0)+,(A1)+
          DBRA    D0,CRL5
          RTS
          
!CRC1     CMPI.B  #'+',D0
          BEQ.S   CRC2
          CMPI.B  #':',D0
          BEQ.L   CRAW
          CMPI.B  #CR,1(A6)       ; folgen noch Zeichen ?
          BEQ     CRC4            ; Nein
          BSET    #4,D7           ; : Auf Reg.-Zuweisung in COU testen
          CLR.L   D3
          BSR.L   COU             ; Registerzuweisungen auswerten
          MOVE.L  D3,D4           ; Eingegebene Register wieder ausgeben
          BRA.S   CRC3
!CRC2     MOVEQ   #-1,D4          ; ALLE REG. ANZEIGEN
          LSR.L   #1,D4           ; Clr Bit 31 : SR nicht als Flags anzeigen
          BRA.S   CRC3
!CRC5     BSR.L   TSTNCR          ; NUR REG.,DIE MIT 'O'-FUNKTION BESTIMMT
          MOVE.L  RegWahl(A4),D4
!CRC3     BSET    #11,D7          ; : KEIN LF BEIM ERSTEN CR AUSGEBEN
;
; Gibt mehrere Register aus. Auswahl in D4. Wenn nur Namen ausg.(#0 set in D7)
;  dann muž von Aufrufer CR und Prompt ausgegeben werden.
;
!CRU      TST.L   D4
          BPL     CRUC9
          BSET    #2,D7           ; : SR als Flags ausgeben
!CRUC9    CLR.W   D3              ; Z„hler f. Registernummer (TNr..)
          BSET    #9,D7           ; : Anfang der Zeile
          BTST    #0,D7           ; Inhalte ausgeben ?
          BNE.S   CRUC1           ; Nein
          
          ;Test, ob D0-A7 angezeigt werden
          MOVE.L  D4,-(A7)        ; REG.AUSWAHL RETTEN
          MOVE.L  #$1FFFE,D0      ; MASKE F. ALLE 16 D-/A- REG.
          AND.L   D0,D4
          CMP.L   D0,D4           ; ALLE 16 REG. ANZEIGEN ?
          BNE.S   CRUC0           ; NEIN
          
(*
          ; 0 .. 7 ausgeben
          BSR     PrtCRLF
          CLR.W   D3
!CRUL3    MOVEQ   #8,D1
          BSR     PrtMSPC
          MOVE.B  D3,D0
          BSR     PrtNIBL
          ADDQ.W  #1,D3
          CMPI.B  #8,D3
          BCS     CRUL3
*)
          MOVEQ   #TNRD0,D3
          BSET    #10,D7
          
!CRUC0    MOVE.L  (A7)+,D4        ; REG.AUSWAHL WIEDER V. STACK

!CRUC1    ; Ausgabeschleife:

!CRL0     MOVE.W  D3,D2
          BTST    D3,D4           ; soll Reg.(D3) ausgegeben werden ?
          BEQ.S   CRUE
          
          BTST    #0,D7           ; Nur Namen ausgeben ?
          BNE.S   CRUC2
          
          BCLR    #9,D7           ; Nein : Anfang der Zeile ?
          BNE     CRUC6           ; Ja
          
          ; Bestimme vorrausichtliche L„nge der folg. Ausgabe
          MOVEQ   #ZEILLEN-12,D0
          CMPI    #TNrSR,D3
          BNE     CRUC7
          ADDQ.W  #4,D0
          BTST    #2,D7
          BEQ     CRUC7
          MOVEQ   #ZEILLEN-24,D0
!CRUC7    CMP     CursorX(A4),D0
          BCC     CRUC2          ; Reg. pažt noch in Zeile
          
!CRUC6    ; Am Anfang der Zeile Kennungzeichen ausgeben
          BSR     PRTPRMPT
          BTST    #10,D7
          BEQ     CRUC3
          
          ; 'D' bzw. 'A' am Zeilenanfang ausgeben
          CMPI.B  #TNRD0,D2
          BNE.S   CRUC4
          MOVEQ   #'D',D1
          BRA.S   CRUC5
!CRUC4    CMPI.B  #TNRA0,D2
          BNE.S   CRUC3
          MOVEQ   #'A',D1
!CRUC5    MOVEQ   #';',D0
          BSR     Prt
          MOVE.B  D1,D0
          BSR     Prt
          BRA.S   CRUC2

!CRUC3    ; 'R' am Zeilenanfang ausgeben
          MOVEQ   #'R',D0
          BSR     Prt
          
!CRUC2    BSR     PrtREG          ; REG. (D2) ANZEIGEN

!CRUE     TST.W   D3
          BNE.S   CRUE2
          BCLR    #10,D7
          BNE.S   CRCE2
          
!CRUE2    ADDQ.W  #1,D3
          CMPI.B  #TNRlast,D3
          BLS     CRL0

!CRCE     CLR.W   D3
          BTST    #10,D7
          BNE     CRL0
!CRCE2    RTS
;
!ChkRegNo CMPI.B  #TNRA7,D2      ; A7 ?
          BNE.S   ChkRNE
          BTST    #5,RgSR(A4)    ; S-Bit in SR gesetzt ?
          BEQ     BRGC4
          MOVEQ   #TnrSSP,D2     ; JA,DANN NR. F. SSP
          BRA     ChkRNE
!BRGC4    MOVEQ   #TnrUSP,D2     ; sonst NR. F. USP
ChkRNE    RTS
;
!BERREGNR BCLR    #2,D7          ; erstmal r�cksetzen...
          BCLR    #3,D7          ; erstmal r�cksetzen...
          CMPI.B  #'F',D0
          BEQ.S   BERSRBIN        ; SR-FLAG ANGABE
          MOVE.B  D0,D1
          BSR.L   GETNGRKL
          BMI     ERR7            ; S.U.
          LEA     REGTAB(PC),A1
          LEA     REGTABEND(PC),A0
          CLR.W   D2
!BRGL1    CMP.B   (A1),D1         ; SUCHE REG.NAME
          BEQ.S   BRGC1
!BRGC2    ADDQ.L  #3,A1
          ADDQ.W  #1,D2
          CMPA.L  A0,A1
          BCS.S   BRGL1
          BRA.L   ERR7            ; UNGšLTIGES REG.
          
!BRGC1    BSR.L   GETLGRKL
          CMP.B   1(A1),D0
          BNE.S   BRGC2
          CMPI.B  #' ',2(A1)
          BEQ     BRGC5
          MOVE.B  1(A6),D0
          BSR     CAPS
          CMP.B   2(A1),D0
          BNE.S   BRGC2
          BSR.L   GETNGRKL
!BRGC5    BSR     ChkRegNo
          BRA.L   GETNGRKL
;
!BERSRBIN BSR.L   GETNGRKL
          BMI.S   BERSRC2
          CMPI.B  #SPC,D0
          BEQ.S   BERSRC2
          BSET    #2,D7
          LEA     SRTAB(PC),A1
!BERSRL1  MOVE.B  (A1),D2
          BEQ     ERR7            ; S.O.
          CMP.B   D2,D0
          BEQ.S   BERSRC1
          ADDQ.L  #3,A1
          BRA.S   BERSRL1

!BERSRC1  MOVE.B  1(A1),D2        ; BITNR. DES SR NACH D2
          ADDQ.L  #1,A6
          RTS

!BERSRC2  MOVEQ   #TNRSR,D2      ; SR gewaehlt (mit 'F' )
          BSET    #3,D7
          RTS
;
; REGISTER-EINGABE 2
;
!ComdSEMK BCLR    #11,D7
          BSR.L   SKIPSPC
          MOVEQ   #TNRD0,D2
          CMPI.B  #'D',D0
          BEQ.S   CSCC1
          CMPI.B  #'A',D0
          BNE     ERR14
          MOVEQ   #TNRA0,D2
!CSCC1    MOVEQ   #7,D4
          LEA     REGBEG(A4),A1
          BSR.L   GETNGRKL
!CSCL1    BSR.L   SKIPSPC
          BMI.S   CSCE
          BSR.L   GETLONGX
          BSR     ChkRegNo
          MOVE    D2,D3
          LSL.W   #2,D3     ; TNR * 4
          MOVE.L  D1,0(A1,D3.W)
          ADDQ.W  #1,D2
          DBF     D4,CSCL1
!CSCE     RTS
;
; Register Ein- / Ausgabe
;
!COUC6    ; SR-Flag setzen:
          BSR.L   SKIPSPCN
          BSR.L   GETBYTE         ; BYTE-WERT HOLEN
          MOVE.B  2(A1),D0        ; A1 ENTHAELT ADR.AUF SRTAB: MASKE LADEN
          CMP.B   D0,D1           ; GROESSE TESTEN MIT MASKE
          BHI     ERR2            ; ZU GROSSER WERT
          EXT.W   D0
          EXT.W   D1
          LSL.W   D2,D0           ; MASKE IN RICHTIGE POS. SCHIEBEN
          LSL.W   D2,D1           ; WERT IN RICHTIGE POS. SCHIEBEN
          NOT.W   D0              ; MASKE NEGIEREN
          AND.W   D0,RgSR(A4)     ; BETREFFENDE BITS LOESCHEN
          OR.W    D1,RgSR(A4)     ; BETREFFENDE BITS ERSETZEN
          BRA.S   COUC7

!COUL1    BSR.L   BERREGNR        ; Registernummer holen
          BTST    #4,D7           ; VON 'R:'-FUNKTION AUFGERUFEN ?
          BEQ.S   COUC3           ; Ja, nicht auf Zuweisung testen
          
          BSR.L   SKIPSPC
          CMPI.B  #'=',D0         ; REG.-ZUWEISUNG ?
          BNE.S   COUC3
          BCLR    #2,D7           ; SR-FLAG ZUWEISUNG ?
          BNE.S   COUC6
          BSR.L   SKIPSPCN
          CMPI.B  #TNRSR,D2       ; ZUW. IN SR ?
          BNE.S   COUC4
          BSR.L   GETWORD         ; JA,NUR 2 BYTE HOLEN
          BRA.S   COUC5
!COUC4    BSR.L   GETLONGX        ; SONST 4 BYTE HOLEN
!COUC5    LEA     REGBEG(A4),A1
          LSL.W   #2,D2
          MOVE.L  D1,0(A1,D2.W)    ; WERT SPEICHERN
          LSR.W   #2,D2
          
!COUC3    BCLR    #3,D7
          BNE     COUC7
          BCLR    #2,D7
          BEQ     COUC1
!COUC7    BSET    #TNRSR,D3
          BSET    #31,D3        ; Flag wurde einzeln zugegriffen
          BRA     COU
!COUC1    BSET    D2,D3
!COU      ;*** aus Eingabepuffer Registernamen holen und ggf. zuweisen
          BSR     SKIPSPC
          BPL     COUL1
          RTS

!CRAW     BCLR    #11,D7
          BSR.L   GETNGRKL
          BMI     COSHOW
          
          CMPI.B  #'-',D0
          BNE.S   COC1
          
          BSR.L   GETNGRKL
          BPL.S   COSUB
          CLR.L   RegWahl(A4)
          RTS
COSUB     CLR.L   D3
          BSR     COU
          NOT.L   D3
          BTST    #0,D3
          BNE     COSUBC0
          BCLR    #31,D3
COSUBC0   AND.L   D3,RegWahl(A4)
          RTS
          
!COC1     CMPI.B  #'+',D0
          BNE.S   COSELCT
          BSR.L   GETNGRKL
          BPL.S   COADD
          MOVE.L  #-1,RegWahl(A4)
          RTS
          
!COSELCT  CLR.L   RegWahl(A4)
!COADD    CLR.L   D3
          BSR     COU
          BTST    #0,D3
          BEQ     COADDC0
          BCLR    #7,RegWahl(A4)
COADDC0   OR.L    D3,RegWahl(A4)
          RTS

!COSHOW   BSET    #0,D7
          MOVE.L  RegWahl(A4),D4
          BRA.L   CRU
;
; SPEICHER-EINGABE
;
!ComdDOPP CMPI.B  #'W',D0
          BEQ     ComdDOPPW
          CMPI.W  #'L',D0
          BEQ.L   ComdDOPPL
          BCLR    #11,D7        ; LF nicht unterdr�cken
          BSR.L   GETADR0       ; ungerade Zahlen erlaubt
          BMI     CCLNEND
          MOVEA.L D1,A1
          MOVE.L  A1,LastMA(A4)
          
!CCLNL1   BSR.S   GETByteX
          MOVE.B  D1,(A1)+
          TST.W   D7
          BPL     CCLNL1
          
!CCLNEND  RTS

GetByteX  ; Liefert Byte, l„žt auch Regs zu
          BSR     SKIPSPC
          CMPI.B  #'R',D0
          BNE     GetByte
          BSR     GetLongX
          ROL.L   #8,D1
          MOVE.B  D1,(A1)+
          ROL.L   #8,D1
          MOVE.B  D1,(A1)+
          ROL.L   #8,D1
          MOVE.B  D1,(A1)+
          ROL.L   #8,D1
          RTS
;
; SPEICHER-EINGABE Word
;
!ComdDOPPW BSR.L  GETNGRKL
          BCLR    #11,D7        ; LF nicht unterdr�cken
          BSR.L   GETADRG       ; ungerade Zahlen nicht erlaubt
          BMI     CCLNENDW
          MOVEA.L D1,A1
          MOVE.L  A1,LastMA(A4)
          
!CCLNL1W  BSR.S   GetWord_X
          MOVE.W  D1,(A1)+
          TST.W   D7
          BPL     CCLNL1W
          
!CCLNENDW RTS

GetWord_X  ; Liefert Byte, l„žt auch Regs zu
          BSR     SKIPSPC
          CMPI.B  #'R',D0
          BNE     GetWord
          BSR     GetLongX
          ROL.L   #8,D1
          MOVE.B  D1,(A1)+
          ROL.L   #8,D1
          MOVE.B  D1,(A1)+
          ROL.L   #8,D1
          RTS
;
; SPEICHER-EINGABE LONG
;
!ComdDOPPL BSR.L  GETNGRKL
          BCLR    #11,D7        ; LF nicht unterdr�cken
          BSR.L   GETADRG       ; ungerade Zahlen nicht erlaubt
          BMI     CCLNENDL
          MOVEA.L D1,A1
          MOVE.L  A1,LastMA(A4)
          
!CCLNL1L  BSR.S   GetLong_X
          MOVE.L  D1,(A1)+
          TST.W   D7
          BPL     CCLNL1L
          
!CCLNENDL RTS

GetLong_X  ; Liefert Byte, l„žt auch Regs zu
          BSR     SKIPSPC
          CMPI.B  #'R',D0
          BNE     GetLong
          BSR     GetLongX
          RTS
;
; TRACE / GO - FUNKTIONEN
;
!ComdT    BMI.S   CTC2
          CMPI.B  #'-',D0
          BNE.S   CTC1
          BSR.L   TSTNCR
          CLR.B   TrcStat(A4)
          BCLR    #7,RgSR(A4)         ; T-FLAG IM SR LOESCHEN
          BRA.S   CTC2
!CTC1     CMPI.B  #'+',D0
          BNE     ERR14
          BSR.L   TSTNCR
          LEA     EyTRC(PC),A0
          MOVE.L  A0,TRACEV          ; TRACE EXCEPTION VEKTOR neu setzen
          MOVE.B  #1,TrcStat(A4)
          BSET    #7,RgSR(A4)         ; T-FLAG IM SR SETZEN
!CTC2     BSR     PrtCRLF
          BSR     PrtTRMOD        ; STATUS DES BIT 0 IN TrcStat(A4) ANZEIGEN
          LEA     SRMSG(PC),A1
          BSR     PrtSTR
          BSET    #8,D7           ; : NUR T-FLAG DES SR ANZEIGEN
          BRA     PrtSRBIN        ; ZUR SR-AUSGABE
;
;
; RTS - ENTRY ( NACH 'GS'-FUNKTION )
;
!EyRTN    BREAK
EyRTNE0   BSR     SetMon          ; hier nur Aufruf von Trace-Routine
EyRTNC0   CLR.L   RgPC(A4)        ; PC LOESCHEN,DA UNBRAUCHBARER INHALT
          LEA     RTNMSG(PC),A1
          BRA     CMDBEG
;
; Go - Funktion
;
!ComdG    BCLR    #11,D7
          MOVE.L  RgPC(A4),D1     ; NEIN: LETZTEN PC šBERNEHMEN
          TST.W   D7              ; ADR.ANGEGEBEN ?
          BMI.S   CGUE
!CGUC1    CMPI.B  #'S',D0         ; GS-BEFEHL ?
          BNE.S   CGUC2
          BSR.L   GETNGRKL        ; JA: TESTEN AUF FOLG. ADR.
          BMI     ERR1
          BSET    #7,D7           ; PEA AUSFšHREN
!CGUC2    BSR     skipspc
          CMPI.B  #',',D0
          BEQ     cmdgc0
          BCLR    #12,D7          ; nur gerade Adr.
          BSR     GETADRG         ; ADR.HOLEN
          BMI     cgue
          
          ; Short BPs auswerten
cmdgl0    CMPI.B  #',',D0
          BNE     ERR4            ; ERROR, WENN KEIN CR oder ',' FOLGT
cmdgc0    CMPI    #shbpanz-1,ShBPcnt(A4)
          BCC     ERR17
          BSR     GetNgrkl
          MOVE.L  D1,-(A7)
          BSR     GETADRG         ; ADR.HOLEN
          BSR.L   InitShortBP
          BSET    #0,ShBPFlg(A4)
          MOVE.L  (A7)+,D1
          BSR     Getlgrkl
          TST     D7
          BPL     cmdgl0
          
!CGUE     TST.L   D1
          BEQ     ERR8            ; ERROR, WENN ADR.=0
          
          MOVEA.L D1,A0
          TST.W   (A0)            ; EXISTIERT RAM/ROM AN DER STELLE ?
                                  ; WENN NICHT, WIRD BUSERROR ERZEUGT.
          MOVE.L  D1,RgPC(A4)         ; NEUEN PC šBERNEHMEN
          
          TST.B   D7              ; GOSUB-COMMAND ?
          BPL.S   CGC2
          
          ; JA: STACKPOINTER LADEN
          BTST    #5,RgSR(A4)
          BNE     CGC70
          LEA     RgUSP(A4),A1
          BRA     CGC71
CGC70     LEA     RgSSP(A4),A1
CGC71     LEA     EyRTN(PC),A5
          MOVE.L  (A1),A0
          MOVE.L  A5,-(A0)        ; RETURN ADR. AUF STACK
          MOVE.L  A0,(A1)         ; NEUEN SP WIEDER SPEICHERN
          
!CGC2     BSR     PrtCRLF         ; CR AUSGEBEN
          
          ST      BPquest(A4)     ; Errors bei SetBPs anzeigen
          
          BSR.L   TSTBP           ; ERFOLGT SPRUNG AUF BP ?
          BEQ.S   CGC3            ; NEIN
          
          ADDQ.W  #1,BPanz+BPanz+BPanz+BPanz+2-4(A0)  ; ZAEHLER UM 1 ERHOEHEN
          
!CGC3     MOVE.B  TrcStat(A4),D7
          ANDI.B  #1,D7           ; BIT0: Tracemode
                                  ; BIT1: TRACE ANZEIGE AN
                                  ; BIT2: KEIN CTRL-BREAK ERFOLGT
                                  ; BIT3: KEIN TEST AUF 'RTS'
                                  ; BIT4: NICHT ANZEIGE WIEDER EIN
                                  ; BIT5: Nach R�ckkehr T-Bit wieder an
                                  ; BIT6: nicht Traceflag wieder l”schen
                                  ; BIT7: Tracebit immer an (alles tracen)
                                  
          BNE.L   TRCGO           ; ZUM TRACEN
          
          CLR.B   ShBPFlg(A4)
          
!CGO      TST.B   D7              ; alles tracen ?
          BPL     cgoc3           ; nein
          
          ; folg. Tests wo anders hin !!!!!!
          ; Test, ob Flp-VBL-Routine gesperrt
          TST.W   $43E
          BNE     cgoc2
          
          ; Test, ob SR =$27xx, sonst wird Tracebit gesetzt:
          MOVE.B  RgSR(A4),D0
          ANDI.B  #$27,D0
          CMPI.B  #$27,D0
          BNE     cgoc20
cgoc2     BCLR    #7,RgSR(A4)     ; in Interrupt-gesperrten Routinen kein Trace
          BRA     cgoc3
cgoc20    BSET    #7,RgSR(A4)
cgoc3
          TST.B   RgSR(A4)        ; SOLL DIESER BEF. GETRACED WERDEN ?
          BMI     CGOC1           ; JA
          
          BTST    #6,D7           ; soll aktueller Bef. �bersprungen werden ?
          BEQ     cgoc0           ; nein

          BSET    #7,RgSR(A4)     ; TRACE-FLAG SETZEN
          BRA     CGoC4           ; BPs, zumindest den auf PC-Adr, nicht setzen

cgoc0     BSR.L   SetBPs          ; BP IM RAM SETZEN
          BNE     cgoTerm         ; Abbruch, weil BPs nicht gesetzt
          BRA     CGoC4

!CGOC1    BCLR    #6,D7           ; k”nne wir vergessen, da T-Bit anbleiben soll
          ;!!! Reicht Abfrage, oder muž auch Bit 4 usw. ber�cksichtigt werden ??
          BTST    #1,D7           ; Erfolgt nach Ausf�hrung wieder Anzeige ?
          BEQ     CgoE0

          ; Nein: Monitor-Screen ausschalten
cgoc4
          LEA     $FF8200,A1
          MOVEP.W 1(A1),D0
          CMP.W   rMonScreen(PC),D0
          BNE     CGoE0
          BSR     NormScrn

CGOE0     MOVE.B  D7,TrcStat(A4)
          SF      BPquest(A4)     ; Errors bei SetBPs nicht anzeigen
          BSR     ResetMon        ; VECTOREN WIEDERHERSTELLEN, Tracing aktiv
          MOVE.L  RgUSP(A4),A0
          MOVE.L  A0,USP
          MOVE.L  RgSSP(A4),A7
          TST.W   StkFrm
          BEQ     noSFload
          MOVE    #$0010,-(A7)    ; Stackframe von Ill.Instr. laden
noSFload  MOVE.L  RgPC(A4),-(A7)
          MOVE.W  RgSR(A4),-(A7)
          MOVEM.L RgD0(A4),D0-A6
(*$ ? ExtendedKeys:
          sf      LockFlag
*)
          RTE

CGoTerm   CLR.W   EntryMod(A4)
          ANDI    #00100001%,D7
          MOVE.B  D7,TrcStat(A4)
          BRA     CMDBEGOM
;
;
!TSTBP    CLR.W   D0
          LEA     BP(A4),A0
          MOVE.L  RgPC(A4),D2
!TSTBPL   CMP.L   (A0)+,D2
          BEQ.S   TSTBPE
          ADDQ.W  #1,D0
          CMPI.W  #BPanz,D0
          BNE     TSTBPL
          RTS
!TSTBPE   CMPI.W  #BPanz,D0
          RTS
;
!TstShBP  MOVE    ShBPcnt(A4),D0
          LEA     ShBP(A4),A0
          MOVE.L  RgPC(A4),D2
          BRA     tbpc0
tbpl0     CMP.L   (A0)+,D2
tbpc0     DBEQ    D0,tbpl0
tbpe0     RTS
;
; TRACE - ENTRY
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyTRC    ; REG. SAVEN (PullRegs)
          PEA     (A4)
          MOVEA.L LocVarP(PC),A4
          ST      MonActive
          MOVEM.L D0-A6,RgD0(A4)
          MOVE.L  (A7)+,RgA4(A4)
          MOVE.W  (A7)+,RgSR(A4)      ; SR VON STACK
          MOVE.L  (A7)+,RgPC(A4)      ; EXCEPTION-RETURN-ADR. VON STACK
          TST.W   is20(A4)
          BNE     is20_2
          CLR.B   RgPC(A4)
is20_2    ADDA.W  StkFrTrc(A4),A7
          MOVE.L  A7,RgSSP(A4)        ; SP SAVEN
          MOVE.L  USP,A0
          MOVE.L  A0,RgUSP(A4)
          MOVE.L  MonStackHi(A4),A7
          BSR     SetMon
          TST.B   BPstat(A4)
          BEQ     eytr0
          BSR.L   ResetBPs        ; BPs RšCKSETZEN
eytr0
          MOVE.B  TrcStat(A4),D7  ; TRACE AKTIV ?
          BNE.S   TRCC1           ; JA

          BCLR    #7,RgSR(A4)     ; Tracebit im SR l”schen und Prg. wieder
          BRA     CGo             ; starten
;
; Upro f. EyRTU & EyDirC: holt RTS-Wert vom Programm-SP nach PC
;
pullPC    BTST    #5,RgSR(A4)
          BEQ     EyRTUC1
          MOVE.L  RgSSP(A4),A0
          ADDQ.L  #4,RgSSP(A4)
          BRA     EyRTUC2
EyRTUC1   MOVE.L  RgUSP(A4),A0
          ADDQ.L  #4,RgUSP(A4)
EyRTUC2   MOVE.L  (A0),RgPC(A4)
          TST.W   is20(A4)
          BNE     is20_3
          CLR.B   RgPC(A4)
is20_3    RTS
;
;                                RšCKKEHR V. 'R' - FUNKTION OHNE TRACE
;
!EyRTU    BREAK                 ; damit kommen wir in den Supervisormode
EyRTUC0   BSR     pullPC
          BSET    #7,RgSR(A4)     ; TRACE-BIT IM SR WIEDER SETZEN
          MOVE.B  TrcStat(A4),D7
          BCLR    #1,D7           ; REG.ANZ. EINSCHALTEN
          
!TRCC1    BTST    #6,D7           ; TRACE-FLAG WIEDER LOESCHEN ?
          BEQ.S   TRCC0           ; NEIN
          BCLR    #7,RgSR(A4)     ; TRACE-FLAG LOESCHEN
          
!TRCC0    LEA     EyRTN(PC),A5
          CMPA.L  RgPC(A4),A5     ; ERFOLGTE RTS AUF EyRTN ?
          BEQ.L   EyRTNE0         ; JA: ZUR CMD-EINGABE
          
          BTST    #2,D7           ; TEST AUF CTRL-BREAK
          BNE.L   EntKbdE1
          
          MOVE.L  UsrBPV,D0       ; USER-BP(A4) VECTOR LADEN
          BEQ.S   TRCC4           ; šBERSPRINGEN,WENN NICHT INITIALISIERT
          
          BTST    #5,RgSR(A4)
          BEQ     TRCC6C0
          MOVE.L  RgSSP(A4),RgA7(A4)
          BRA     TrcC6C1
TrcC6C0   MOVE.L  RgUSP(A4),RgA7(A4)
TrcC6C1   LEA     REGBEG(A4),A0   ; REGISTER-POINTER NACH A0 LADEN
          MOVEA.L D0,A1
          JSR     (A1)
          TST.B   D0
          BEQ     TRCC4
          
          LEA     UsrBPMsg(PC),A1
          BRA     CMDBEG

!TRCC4    BCLR    #4,D7           ; REG.-ANZEIGE WIEDER EINSCHALTEN ?
          BEQ     TRCGO           ; NEIN
          BCLR    #1,D7           ; JA

!TRCGO    BSR.L   TstShBP         ; Short BP erreicht ?
          BNE     TrcGo00         ; Nein

TrcC50    BCLR    #1,D7           ; Anzeige wieder an
          BCLR    #5,D7           ; TRACE-FLAG wieder an ?
          BEQ.S   TRCC51          ; nein
          BSET    #7,RgSR(A4)     ; TRACE-FLAG setzen
!TRCC51   ; ResetShortBP wird automatisch bei TrcCtrl aufgerufen
          LEA     BPMSG(PC),A1
          TST.B   TrcStat(A4)
          BEQ     CMDBEG

TrcGo00   TST.B   BPset(A4)
          BEQ     TrcC6
          BSR.L   TSTBP           ; TEST AUF BP:
          BEQ     TRCC6           ; Nein

!TRCC5    SUBQ.L  #4,A0           ; A0 auf BP-Vektor setzen
          SUBQ.W  #1,BPanz+BPanz+BPanz+BPanz+2(A0) ; ZAEHLER UM 1 VERMINDERN
          BNE.S   TRCC9
          ; ZAEHLER ABGELAUFEN: WIEDER NEU SETZEN
          MOVE.W  BPanz+BPanz+BPanz+BPanz(A0),BPanz+BPanz+BPanz+BPanz+2(A0)
          MOVE.W  D0,EntryNr(A4)
          LEA     BPNMSG(PC),A1
          MOVE.B  #2,EntryMod(A4)
          BRA.L   CMDBEGOC        ; ZUR CMD-EINGABE

!TRCC9    ; diese Instr. im Tracemode ohne Anzg. ausf�hren, falls kein Trace
          BSET    #6,D7           ; T-FLAG setzen und beim FOLG. BEF. LOESCHEN
          BRA     TrcC60

!TRCC6    BCLR    #6,D7           ; WURDE TRACE-FLAG GELOESCHT ?
          BNE     CGO             ; JA

!TRCC60   BTST    #3,D7           ; AUF RTS TESTEN ?
          BEQ.S   TRCC3           ; NEIN

          BTST    #5,RgSR(A4)
          BNE     Trc70
          LEA     RgUSP(A4),A0
          BRA     Trc71
!Trc70    LEA     RgSSP(A4),A0
!Trc71    MOVE.L  TrcSvSP(A4),D0
          CMP.L   (A0),D0         ; STIMMT SP ?
          BHI.S   TRCC3           ; NEIN: NOCH NICHT TESTEN
          MOVEA.L RgPC(A4),A0
          CMPI.W  #BEFRTS,(A0)    ; NAECHSTER BEF. 'RTS' ?
          BEQ.S   TRCC7
          CMPI.W  #BEFRTR,(A0)    ; NAECHSTER BEF. 'RTR' ?
          BEQ.S   TRCC7
          CMPI.W  #BEFRTE,(A0)    ; NAECHSTER BEF. 'RTE' ?
          BNE.S   TRCC3
!TRCC7    BSET    #4,D7           ; : AB NAECHSTEN BEF. WIEDER ANZEIGE EIN !
          BCLR    #3,D7

!TRCC3    BTST    #1,D7           ; REG. ANZEIGEN ?
          BNE     CGO             ; NEIN: BEF. SOFORT AUSFšHREN

!TrcCtrl  ; Trace Kommando Eingabe
          BCLR    #5,D7
          ST      BPquest(A4)     ; Errors bei SetBPs anzeigen
          BCLR    #0,ShBPFlg(A4)
          BNE     TrcCtrlL0       ; ShBPs wurden gerade bei 'G' gesetzt
          BSR.L   ResetShortBPs
TrcCtrlL0 MOVE.W  D7,-(A7)
          CLR.L   D7
          BTST    #11-8,(A7)
          BEQ     TrcCtC0
          BSET    #11,D7
TrcCtC0   MOVE.L  RegWahl(A4),D4
          BCLR    #TNRPC,D4       ; PC VON WAHL AUSSCHLIESSEN
          BSR.L   CRU             ; REG. OHNE PC ANZEIGEN
          MOVEA.L RgPC(A4),A2
          BSR.L   DISASMLN        ; DISASSEMBLIERE FOLG. BEFEHL
          MOVE.L  A2,D6
          MOVE.L  A2,A3
          BSR     PrtCRLF
          MOVE.W  (A7)+,D7
          BCLR    #11,D7
          
          BSR     MonScrn         ; Monitor-Screen einschalten
          
!TRCCTC1  BSR.L   WAITKEY
          BSR.L   CAPS
          
          CMPI.B  #ESCkey,D0
          BEQ     CMDBEGOM        ; ZUR EINGABE OHNE MSG.-AUSGABE
          
          CMPI.B  #'0',D0
          BNE.S   TRCCTC2
          
          BCLR    #7,RgSR(A4)     ; L”sche TRACE-BIT IM SR
          
!TRCCTC20 BSET    #8,D7           ; nur T-Flag anzeigen
          BSR     PrtSRbin
          BSR     PrtCRLF
          BRA     TrcCtC1         ; UND WEITER AUF EINGABE WARTEN
          
!TRCCTC2  CMPI.B  #'1',D0
          BNE.S   TRCCTC22
          
          BSET    #7,RgSR(A4)     ; Setze TRACE-BIT IM SR
          BRA     TrcCtC20
          
!TRCCTC22 CMPI.B  #'F',D0
          BNE.S   TRCCTC21
          
          BCLR    #7,RgSR(A4)     ; L”sche TRACE-BIT IM SR
          BSET    #5,D7           ; bei R�ckkehr wieder T-Bit im SR setzen
          BRA     CGO             ; und weiter (wie mit SPACE)
          
!TRCCTC21 CMPI.B  #'R',D0         ; OHNE TRACE BIS RTS ?
          BNE.S   TRCCTC4
          
          TST.B   RgSR(A4)        ; JA: TRACE-BIT IM SR GESETZT ?
          BMI.S   TRCCTC3         ; JA: MERKEN UND ANZGE. AUS BIS 'RTS'
          
          ; NEIN: STACKPOINTER LADEN
          BTST    #5,RgSR(A4)
          BNE     Trc72
          LEA     RgUSP(A4),A1
          BRA     Trc73
!Trc72    LEA     RgSSP(A4),A1
!Trc73    MOVEA.L (A1),A0
          LEA     EyRTU(PC),A5
          MOVE.L  A5,-(A0)        ; RETURN ADR. AUF STACK
          MOVE.L  A0,(A1)         ; NEUEN SP WIEDER SPEICHERN
          BRA     CGO             ; PRG. AUFRUFEN

!TRCCTC3  BSET    #3,D7           ; : ANZEIGE AUS BIS RTS
          BTST    #5,RgSR(A4)
          BNE     Trc74
          MOVE.L  RgUSP(A4),TrcSvSP(A4)  ; SP MERKEN
          BRA     Trc75
!Trc74    MOVE.L  RgSSP(A4),TrcSvSP(A4)  ; SP MERKEN
!Trc75                                   ; REG.-ANZEIGE AUS UND GO :
          
!TRCCTC5  BSET    #1,D7           ; REG.ANZ. AUSSCHALTEN
          BRA     CGO

!TRCCTC4  CMPI.B  #'O',D0         ; ANZEIGE AUS ?
          BEQ     TRCCTC5

!TRCCTC6  CMPI.B  #' ',D0         ; WEITER TRACEN ?
          BEQ     CGO

!TRCCTC7  CMPI.B  #'A',D0         ; Alles ohne Anzeige tracen ?
          BNE     TRCCTC9
          
          BSET    #7,D7
          BRA     TrcCtC5
          
!TRCCTC9  CMPI.B  #'D',D0         ; Dism next ?
          BNE     TRCCTC11
          
          MOVEQ   #PROMPT,D0
          BSR     Prt
          MOVEQ   #',',D0
          BSR     Prt
          MOVE.L  A2,D6
          BSR.L   DISASM          ; DISASSEMBLIERE FOLG. BEFEHL
          BSR     PrtCRLF
          BRA     TrcCtC1
          
!TRCCTC11 CMPI.B  #'S',D0         ; Skip next ?
          BNE     TRCCTC10
          
          MOVE.L  A3,RgPC(A4)
          LEA     SkipMsg(PC),A1
          BSR     PrtStr
          BRA     TrcCtrlL0
          
!TRCCTC10 CMPI.B  #'B',D0         ; Breakpoint setzen ?
          BNE     TRCCTC1
          
          MOVE.L  D6,D1
          BSR     InitShortBP
          BEQ     TrcCtC1
          LEA     ShBPMsg(PC),A1
          BSR     PrtStr
          MOVE.L  D6,D0
          BSR     PrtLong
          BSR     PrtCRLF
          BRA     TRCCTC1
;
!InitShortBP
          MOVE    ShBPcnt(A4),D0
          CMPI    #ShBPanz,D0
          BEQ     initshbpe
          LEA     ShBP(A4),A0
          LSL     #2,D0
          MOVE.L  D1,0(A0,D0.W)
          ADDQ.W  #1,ShBPcnt(A4)
initshbpe RTS
;
;
SBrkErr   MOVE.L  D5,A7
          BRA     SBRKER2
          
!SetBRK   MOVE.W  (A1),(A2)
          MOVE.W  #BEFBRK,(A1)
          CMPI.W  #BEFBRK,(A1)
          BNE     SBrkEr2
          BSET    D4,D3
          RTS
SBrkEr2   TST.B   BPquest(A4)
          BEQ     SBrkEr3
          MOVE    D0,-(A7)
          PEA     (A1)
          LEA     BPErrMsg(PC),A1
          BSR     PrtStr
          MOVE.L  (A7)+,D0
          BSR     PrtAdr
          BSR     PrtCRLF
          MOVE    (A7)+,D0
          MOVEQ   #1,D2
SBrkEr3   RTS
;
!SETBPs   MOVE.L  BUSERRV,-(A7)
          LEA     SBRKErr(PC),A0
          MOVE.L  A0,BUSERRV
          MOVE.L  A7,D5
          SUBQ.L  #4,D5
          CLR     D2
          CLR     D4
          LEA     BP(A4),A0
          LEA     BPSV(A4),A2
          MOVE.B  BPstat(A4),D3
          BEQ     SBPL1
          MOVE.L  (A7)+,BusErrV
          BRA     Err18           ; Fehler !!! Darf nicht eintreten
!SBPL1    TST.L   (A0)+
          BEQ     SBPC1
          MOVEA.L -4(A0),A1
          BSR     SetBrk
!SBPC1    ADDQ    #2,A2
          ADDQ    #1,D4
          CMPI.B  #BPanz,D4
          BCS     SBPL1
          MOVE.B  D3,BPstat(A4)
          
          ; SetShBPs
          CLR     D3
          MOVE    ShBPcnt(A4),D0
          BEQ     sshbpe0
          CLR     D4
          LEA     ShBP(A4),A0
          LEA     ShBPsv(A4),A2
          BRA     sshbpc0
sshbpl0   MOVEA.L (A0)+,A1
          BSR     SetBrk
          ADDQ    #2,A2
          ADDQ    #1,D4
sshbpc0   DBRA    D0,sshbpl0
sshbpe0   MOVE    D3,ShBPstat(A4)
          MOVE.L  (A7)+,BusErrV
          
          TST     D2
          BEQ     SBPTE0
          BSR     MonScrn
          LEA     PressKeyMsg(PC),A1
          BSR     PrtStr
SBPTL     BSR     WaitKey
          CMP.B   #' ',D0
          BEQ     SBPTE0
          CMP.B   #ESCkey,D0
          BNE     SBPTL
          MOVEQ   #1,D2
SBPTE0    RTS
;
!ResetBPs ; A0/D7 m�ssen erhalten bleiben !!!
          CLR.B   D0              ; BP(A4) LOESCHEN,ALTEN WERT WIEDERHERSTELLEN
          LEA     BP(A4),A3
          LEA     BPsv(A4),A2
!RBPL1    BCLR    D0,BPstat(A4)
          BEQ.S   RBPC1
          MOVEA.L (A3),A1
          CMPI.W  #BEFBRK,(A1)    ; STEHT BRK-BEF. NOCH IM SPEICHER ?
          BNE.S   RBPC1           ; NEIN: SPEICHERINHALT NICHT AENDERN
          MOVE.W  (A2),(A1)       ; ALTEN WERT ZURšCKSPEICHERN
!RBPC1    ADDQ.L  #4,A3
          ADDQ.L  #2,A2
          ADDQ.B  #1,D0
          CMPI.B  #BPanz,D0
          BCS     RBPL1
          RTS
;
!ResetShortBPs ; alle ShortBPs l”schen
          CLR.B   ShBPFlg(A4)
          MOVE    ShBPstat(A4),D3
          BEQ     rbpe0           ; nicht im RAM gesetzt -> OK. und Ende.
          CLR     ShBPstat(A4)
          MOVE    ShBPcnt(A4),D0
          CLR     D2
          LEA     ShBP(A4),A1
          LEA     ShBPsv(A4),A2
          BRA     rbpc2
rbpl2     BTST    D2,D3
          BEQ     rbpc3           ; BP wurde nicht ins RAM gesetzt
          MOVE.L  (A1),A0         ; Adr. des BP laden
          CMPI.W  #BEFBRK,(A0)    ; STEHT BRK-BEF. NOCH IM SPEICHER ?
          BNE.S   RBPC3           ; NEIN: SPEICHERINHALT NICHT AENDERN
          MOVE.W  (A2),(A0)       ; ALTEN WERT ZURšCKSPEICHERN
rbpc3     ADDQ    #4,A1
          ADDQ    #2,A2
          ADDQ    #1,D2
rbpc2     DBRA    D0,rbpl2
rbpe0     CLR     ShBPcnt(A4)
          RTS
;
; DISASSEMBLER
;
!ComdD    LEA     LastDA(A4),A1
          BCLR    #12,D7          ; nur gerade Adr.
          BSR.L   GETAE
          BPL     ERR4
!CDL1     BSR.L   DISASMLN
          BSR.L   TSTKEY
          BNE     CDE
          BTST    #1,D7
          BNE.S   CDC1
          CMPA.L  A3,A2
          BCS     CDL1
          BRA.S   CDE
!CDC1     SUBQ.L  #1,D3
          BNE     CDL1
!CDE      MOVE.L  A2,LastDE(A4)
          RTS
;
; FšLL- UND SUCH- FUNKTIONEN
;
!GETFNDBF BSR.L   SKIPSPC
          BMI     ERR9
          MOVEQ   #-1,D2          ; ZAEHLER F. ANZAHL DER EINGEGEBENEN ZEICHEN
          CLR.L   D3              ; JOKER-MERKER
          LEA     FindBuf(A4),A1  ; ANF. DES BUFFERS F. ZEICHEN
          BSR.L   TSTHZIFF        ; HEX-BYTE-EINGABE ?
          BEQ     GETFBHC0        ; JA
          BSET    #4,D7           ; NEIN: STRING-EINGABE
          MOVE.B  D0,D4           ; DELIMITER MERKEN
          ADDQ.L  #1,A6
          MOVEA.L A6,A5           ; ADRESSE IM COMMAND-STRING MERKEN
!GETFBAL  MOVE.B  (A6)+,D0        ; NAECHSTES ZEICHEN LADEN
          CMP.B   D4,D0           ; 2. DELIMITER ?
          BEQ.S   GETFBE1         ; JA:ENDE
!GETFBHL  CMPI.B  #CR,D0          ; CR ?
          BEQ.S   GETFBE2         ; JA:ENDE
!GETFBHC0 ADDQ.W  #1,D2
          CMPI.B  #32,D2          ; SCHON MEHR ALS 32 ZEICHEN ?
          BEQ     ERR10           ; JA: ERROR
          CMPI.B  #JOKER,D0       ; JOKER ?
          BNE.S   GETFBAC1
          BSET    D2,D3           ; JA: JOKERFLAG SETZEN
          BTST    #4,D7
          BNE     GETFBAL
          ADDQ.L  #1,A6
          BRA.S   GETFBHC2
!GETFBAC1 BTST    #4,D7
          BEQ.S   GETFBHC1
          MOVE.B  D0,0(A1,D2.W)   ; ZEICHEN MERKEN
          BRA.L   GETFBAL
!GETFBHC1 BSR.L   GETLGRKL        ; LETZTES ZEICHEN WIEDER NACH D0
          BSR.L   GETBYTE         ; BYTE-WERT HOLEN
          MOVE.B  D1,0(A1,D2.W)   ; ZEICHEN MERKEN
!GETFBHC2 BSR.L   SKIPSPC
          BRA.L   GETFBHL

!GETFBE1  BSR.L   GETLGRKL        ; FOLGT CR ? NEIN: ERROR
          BPL     ERR4
!GETFBE2  TST.W   D2
          BMI     ERR9            ; ERROR: KEIN ZEICHEN EINGEGEBEN
          RTS
;
!ComdF    BCLR    #11,D7
          LEA     Hilf1L(A4),A1
          BSET    #12,D7          ; Ungerade Adr. erlaubt
          BSR.L   GETAE           ; HOLE ANF.- UND END - ADR.
          BEQ     ERR11           ; ERROR: BEIDE ADR. ANGEBEN !
          BSR.L   GETFNDBF        ; HOLE SUCH-/ FšLL-STRING
!CFL1     CLR.L   D4              ; ZAEHLER F. STRINGLAENGE
!CFL2     BTST    D4,D3           ; JOKER ?
          BNE.S   CFC1            ; JA: SPEICHERSTELLE NICHT FšLLEN
          MOVE.B  0(A1,D4.W),(A2) ; SPEICHERSTELLE FšLLEN
!CFC1     ADDQ.L  #1,A2
          CMPA.L  A3,A2           ; ENDADR. ERREICHT ?
          BCC.S   CFEND
          ADDQ.W  #1,D4
          CMP.W   D2,D4           ; GANZER STRING GESPEICHERT ?
          BLS     CFL2            ; NEIN: NAECHSTES ZEICHEN
          BRA.L   CFL1            ; JA: MIT STRING WIEDER VON VORN BEGINNEN
          
!CFEND    RTS
;
!ComdH    BCLR    #11,D7
          LEA     Hilf1L(A4),A1
          BSET    #12,D7          ; Ungerade Adr. erlaubt
          BSR.L   GETAE           ; HOLE ANF.- UND END - ADR.
          BEQ     ERR11           ; ERROR: BEIDE ADR. ANGEBEN !
          BSR.L   GETFNDBF        ; HOLE SUCH-/ FšLL-STRING
          BSR     PrtCRLF
          BSR     PrtSPC
          MOVEQ   #10,D5
          TST     is20(A4)
          BEQ     CHC7
          MOVEQ   #8,D5           ; bei Long-Adressen nur 8 Werte pro Zeile
!CHC7     MOVE    D5,-(A7)
!CHL1     CLR.L   D4              ; ZAEHLER F. STRINGLAENGE
!CHL2     BTST    D4,D3           ; JOKER ?
          BNE.S   CHC2            ; JA: NAECHSTES ZEICHEN VERGLEICHEN
          MOVE.B  0(A2,D4.W),D0   ; ZEICHEN AUS SPEICHER LADEN
          CMP.B   0(A1,D4.W),D0   ; MIT STRING IDENTISCH ?
          BEQ.S   CHC2            ; JA
!CHC3     ADDQ.L  #1,A2
          CMPA.L  A3,A2
          BCS     CHL1
!CHC6     ADDQ.L  #2,A7
          RTS
          
!CHC2     ADDQ.W  #1,D4
          CMP.B   D2,D4           ; GANZER STRING VERGLICHEN ?
          BLS     CHL2            ; NEIN: NAECHSTES ZEICHEN VERGLEICHEN
          LEA     FindBuf(A4),A0
          CMPA.L  A0,A2           ; ADR = SUCHSTRING-BUFFER ?
          BEQ     CHC3
          CMPA.L  A5,A2           ; ADR = EINGABE-BUFFER ?
          BEQ     CHC3
          
          ; STRING GEFUNDEN -> ausgeben
          MOVE.L  A2,D0
          BSR     PrtADR          ; ADR. AUSGEBEN
          SUBQ.W  #1,D5
          BNE     CHC4
          BSR     PrtCRLF
          MOVE    (A7),D5
          BRA     CHC5
CHC4      BSR     PrtSPC
CHC5      BSR     PrtSPC
          BSR.L   TSTKEY          ; TASTE GEDRšCKT ?
          BEQ     CHC3            ; NEIN: WEITERE STRINGS SUCHEN
          BRA     CHC6            ; JA: ABBRUCH
; "Q"
!ComdQ    BPL     ERR4
          BSR.L   PrntClose
          BSR     ResetMon        ; VECTOREN WIEDERHERSTELLEN
          BSR     NormScrn        ; Monitor-Screen ausschalten
          BSR     ClrBPs          ; BPs l”schen
(*
          MOVE.L  RgUSP(A4),A0
          MOVE.L  A0,USP
*)
          MOVE.L  A7,USP          ; Bei Quit wird Mon-SP verwendet, damit
                                  ; nicht evtl. Buserror, wenn Orig-SP defekt
          MOVE.L  RgSSP(A4),A7    ; SSP und USP d�rfen sich nicht �berlagern!

          MOVE.W  RgSR(A4),D0
          ANDI    #$78FF,D0       ; IR-Level auf 3, Trace aus
          ORI     #$0300,D0
          MOVE.W  D0,SR

          ; TERM:
          
(*$ ? ExtendedKeys:
          sf      LockFlag
*)
          MOVE.W  #-1,-(A7)
          MOVE.W  #$4C,-(A7)
          TRAP    #1
          ; hier geht's weiter, wenn TERM nicht ging:
          BRA     CmdLoop
; "&"
!ComdDEZ  MOVE.L  #$FFFFFFF,D6
          CLR.L   D1
          BSR.L   GETDEZ
          BPL     ERR4
          BCLR    #11,D7
          MOVEQ   #'=',D0
          BSR     Prt
          MOVE.L  D1,D0
          BRA     PrtLONG
;
; ADRESS / BUS-ERROR ENTRY
;
!STOEADR  MOVE.L  A4,SvA4
          MOVEA.L LocVarP(PC),A4
          ST      MonActive
          MOVEM.L D0-A6,RgD0(A4)
          MOVE.L  SvA4,RgA4(A4)
          
          BSR     SetMon
          
          MOVEA.L (A7)+,A3        ; RTS-ADR. V. STACK HOLEN
          BSR.L   PULLEADR        ; SR,PC V. STACK HOLEN
          
          MOVE.L  A7,RgSSP(A4)    ; STACKPOINTER ABSPEICHERN
          MOVE.L  USP,A0
          MOVE.L  A0,RgUSP(A4)
          MOVE.L  MonStackHi(A4),A7
          MOVE.W  D2,RgSF(A4)
          MOVE.L  D1,ErrAdr(A4)   ; ERROR-ADR. SPEICHERN
          MOVE.W  D6,SupSR(A4)    ; SUPER-STATUS-WORT SPEICHERN
          MOVE.W  D4,ErrBef(A4)   ; BEF.-CODE SPEICHERN
          MOVE.W  D5,RgSR(A4)     ; SR ABSPEICHERN
          ; BEF.WORT VOR PC-ADR. SUCHEN:
          TST     StkFrm
          BNE     STOEC2          ; bei 68020 nicht suchen
          MOVEQ   #-2,D0
!STOEL1   CMP.W   0(A5,D0.W),D4   ; VERGL. BEF.-CODE  A5: PC
          BEQ     STOEC1
          SUBQ.W  #2,D0
          CMPI.W  #-10,D0         ; SCHON MEHR ALS 10 BYTE ZURšCK ?
          BCC     STOEL1          ; NEIN: WEITER SUCHEN
          BRA     STOEC2          ; JA: BEF.-CODE NICHT GEFUNDEN
!STOEC1   ADDA.W  D0,A5
!STOEC2   MOVE.L  A5,RgPC(A4)     ; PC ABSPEICHERN
          TST.W   is20(A4)
          BNE     is20_4
          CLR.B   RgPC(A4)
is20_4
          MOVE.B  #5,EntryMod(A4) ; 'Exception :' ausgeben
          JMP     (A3)            ; RTS
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyBUS    BSR     STOEADR
          MOVE    #2,ExcNo(A4)
          LEA     BEMSG(PC),A1
          BRA     CMDBEGOC
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyADR    BSR     STOEADR
          MOVE    #3,ExcNo(A4)
          LEA     AEMSG(PC),A1
          BRA     CMDBEGOC
;
;
;
!PULLREGS MOVE.L  A4,SvA4
          MOVEA.L LocVarP(PC),A4
          ST      MonActive
          MOVEM.L D0-A6,RgD0(A4)
          MOVE.L  SvA4,RgA4(A4)

          TST     is20(A4)
          BEQ     is20_5_01
          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
          DC.W    $0000               ;           Rn = D0, Rc = SFC
          MOVE.L  D0,RgSFC(A4)
          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
          DC.W    $0001               ;           Rn = D0, Rc = DFC
          MOVE.L  D0,RgDFC(A4)
          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
          DC.W    $0002               ;           Rn = D0, Rc = CACR
          MOVE.L  D0,RgCACR(A4)
;          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
;          DC.W    $0800               ;           Rn = D0, Rc = USP
;          MOVE.L  D0,RgUSP(A4)
          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
          DC.W    $0801               ;           Rn = D0, Rc = VBR
          MOVE.L  D0,RgVBR(A4)
          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
          DC.W    $0802               ;           Rn = D0, Rc = CAAR
          MOVE.L  D0,RgCAAR(A4)
          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
          DC.W    $0803               ;           Rn = D0, Rc = MSP
          MOVE.L  D0,RgMSP(A4)
          DC.W    $4E7A               ; MOVEC.L   Rc     , Rn
          DC.W    $0804               ;           Rn = D0, Rc = ISP
          MOVE.L  D0,RgISP(A4)

is20_5_01
          MOVEA.L (A7)+,A1            ; RETURN-ADR. VON STACK HOLEN
          MOVE.W  (A7)+,RgSR(A4)      ; SR VON STACK
          MOVE.L  (A7)+,RgPC(A4)      ; EXCEPTION-RETURN-ADR. VON STACK
          TST.W   is20(A4)
          BNE     is20_5
          CLR.B   RgPC(A4)
is20_5
          TST     StkFrm
          BEQ     noFrame
          
          ; Stack-Rest bei 68020 abr„umen
          MOVE.W  (A7)+,D0
          MOVE    D0,RgSF(A4)
          ROL     #5,D0
          ANDI    #$1E,D0
          LEA     SFTbl(PC),A0
          ADDA.W  0(A0,D0.W),A7

noFrame   MOVE.L  A7,RgSSP(A4)        ; SP SAVEN
          MOVE.L  USP,A0
          MOVE.L  A0,RgUSP(A4)
          MOVE.L  MonStackHi(A4),A7
          PEA     (A1)
          TST.W   is20(A4)
          BNE     is20_6
          CLR.B   (A7)
is20_6
          
          TST     StkFrm
          BEQ     noFrame3
          CLR     D0
          MOVE.W  RgSF(A4),D0
          ANDI    #$FFF,D0
          MOVE    D0,ExcNo(A4)
          BRA     hadFrm2
noFrame3  MOVE.L  A1,D0
          SWAP    D0
          LSR.W   #8,D0
          MOVE    D0,ExcNo(A4)
hadFrm2   MOVE.B  #4,EntryMod(A4) ; 'Exception :' ausgeben
          BRA     SetMon

SFTbl     DC.W    0,0,4,0,0,0,0,0,50,12,24,80,0,0,0,0
;
; ILLEGAL CMD - ENTRY ( VEKTORNR.4 )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyILL    BSR     PULLREGS
          MOVEA.L RgPC(A4),A0
          CMPI.W  #BEFBRK,(A0)    ; WAR ILL.BEF. BREAK-BEFEHL ?
          BEQ     EILLBRK         ; JA
          LEA     ILLMSG(PC),A1
          BRA     CMDBEGOC
          
!EILLBRK  BSR.L   ResetBPs         ; BPs RšCKSETZEN
          LEA     EyRTN(PC),A1
          CMPA.L  A0,A1           ; Aufruf von EyRTN ?
          BEQ     EyRTNC0         ; JA
          LEA     EyRTU(PC),A1
          CMPA.L  A0,A1           ; Aufruf von EyRTU ?
          BEQ     EyRTUC0         ; JA
          LEA     EyDirC(PC),A1
          CMPA.L  A0,A1           ; Aufruf von EyDirC ?
          BEQ     EyDirCCo        ; JA

          MOVE.B  TrcStat(A4),D7
          BSET    #1,D7           ; Anzg. aus
          BSR     TSTBP           ; TEST AUF BP:
          BNE     TRCC5           ; Ja

          BSR     TstShBP         ; Short BP erreicht ?
          BEQ     TrcC50          ; ja

          ADDQ.L  #2,RgPC(A4)     ; PC HINTER BRK-BEF. SETZEN
          LEA     BRKMSG(PC),A1   ; ZUM WARMSTART
          BRA     CMDBEG
;
; Direct call entry (via $64, IRQ 1)
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyDirC   BREAK
EyDirCCo  BSR     pullPC
          LEA     DirCMSG(PC),A1
          BRA     CMDBEG
;
; Frame Error - Entry ( Vectornr.$38 )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyFrm    BSR.L   PULLREGS
          LEA     FrmErMSG(PC),A1
          BRA.L   CMDBEGOC
;
; Illegal Interrupt - Entry ( Vectornr.$18 )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyILLIRQ BSR.L   PULLREGS
          LEA     ILLIMSG(PC),A1
EntryC0   BRA.L   CMDBEGOC
;
; Interrupt - Entry ( Vectornr.$19-$1F )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyIRQ    BSR.L   PULLREGS
          MOVE    ExcNo(A4),D0
          SUBI    #24,D0
          MOVE    D0,EntryNr(A4)
          BSET    #1,EntryMod(A4)
          LEA     IRQMSG(PC),A1
          BRA     EntryC0
;
; TRAP - Entries ( Vectornr.$20-$2F )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyTRAP0  BSR.L   PULLREGS
          MOVE    ExcNo(A4),D0
          SUBI    #32,D0
          MOVE    D0,EntryNr(A4)
          BSET    #1,EntryMod(A4)
          LEA     TRAPMSG(PC),A1
          BRA     EntryC0
;
; TrapV - Entry ( Vectornr.$07 )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyTRAPV  BSR.L   PULLREGS
          LEA     TRPVMSG(PC),A1
          BRA     EntryC0
;
; CHK - Entry ( Vectornr.$06 )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyCHK    BSR.L   PULLREGS
          LEA     CHKMSG(PC),A1
          BRA     EntryC0
;
; Div by Zero - Entry ( Vectornr.$05 )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyDIV    BSR.L   PULLREGS
          LEA     DIVMSG(PC),A1
          BRA     EntryC0
;
; Privilegsverletzungs - Entry ( Vectornr.$08 )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyPRIV   BSR.L   PULLREGS
          LEA     PRIVMSG(PC),A1
          BRA     EntryC0

(*$ ? ExtendedKeys:
;
; IKBDSYS
;
; **************************************************************************
;
          ASC     'XBRA'
          ASC     'TMon'
!OldIKBDSYS
          DC.L    0
!EyIKBDSYS
          move.l    KeyIORcV(PC),a0
          move.w    8(a0),-(sp)         ; Tail Index merken
          move.l    OldIKBDSYS(PC),a0
          jsr       (a0)                ; alte Routine ausf�hren
          move.l    KeyIORcV(PC),a0     ; Iorec Pointer holen
          move.w    8(a0),d1            ; Neuen Tailindex holen
          cmp.w     (sp)+,d1            ; mit altem vergleichen
          beq       nokey
          move.l    0(a0),a1            ; Zeiger auf IO Puffer
          move.l    0(a1,d1.w),d0       ; letzte Taste (ASC 0-7; Scan 16-23)
          swap      d0                  ; ScanCode nach 0-7
          cmp.b     tmon_scancode(PC),d0
          beq.s     war_help
          cmp.b     reset_scancode(PC),d0
          beq.l     war_del
          cmp.b     sync_scancode(PC),d0
          beq.l     war_mal
          cmp.b     sync_on(PC),d0
          beq.l     switch_intern
          cmp.b     sync_off(PC),d0
          beq.l     switch_extern
!return_ikbd
!nokey
          rts

!kill_key
          move.l    KeyIORcV(PC),a0     ; Iorec Pointer holen
          move.w    8(a0),d1            ; neuen Tailindex holen
          subq.w    #4,d1
          bpl.s     kill_repeat
          move.w    6(a0),d1
!kill_repeat
          move.w    d1,8(a0)
          move.l    KbshiftV(PC),a0
          clr.w     d1
          move.b    d1,$1e(a0)          ; Repeat Taste
          move.b    d1,$1f(a0)          ; Z„hler f�r Startverz”gerung
          move.b    d1,$20(a0)          ; Z„hler f�r Repeat Rate
          bra       return_ikbd

;*************************************************************************

!war_help                             ; Tastendruck von Help auswerten
        movem.l   a0/d0,-(sp)         ; d0 sichern
        bsr       KbShift
        andi.b    #$f,d0
        cmp.b     tmon_shiftkeys(PC),d0
        bne       end_help
        tst.b     LockFlag            ; Monitor gerade aktiv
        bne       end_help            ; dann nicht nocheinmal aufrufen
        st        CallFlag
        movem.l   (sp)+,a0/d0
        bra       kill_key
!end_help
        movem.l   (sp)+,a0/d0
        bra.l     return_ikbd
;
!war_del            movem.l   d0/a3,-(sp)         ; Registersicherung
                    movea.l   $4f2,a3             ; _sysbase
                    cmpi.w    #$0102,2(a3)
                    bhi       reset_in_neuem_tos
                    bsr       KbShift
                    andi.b    #$f,d0
                    cmp.b     reset_warm_shiftkeys(PC),d0
                    beq.s     warmstart
                    cmp.b     reset_kalt_shiftkeys(PC),d0
                    beq.s     kaltstart           ; (Alt + Cntrl + Shift)
!reset_in_neuem_tos
                    movem.l   (sp)+,d0/a3         ; war nix f�r uns; Register-
                    bra       return_ikbd         ; restaurierung und zur�ck

!kaltstart          clr.l     $420                ; L”sche alle memvalid's
                    clr.l     $426                ; auch den f�r'n Resetvektor
                    clr.l     $43a
                    clr.l     $51a
                    movea.l   4,a0
                    jmp       (a0)
!warmstart          movea.l   $4f2,a0             ; _sysbase
                    jmp       (a0)                ; Ab ins Betriebssystem

;

!war_mal            move.l    d0,-(sp)            ; Registersicherung
                    bsr       KbShift
                    andi.b    #$f,d0
                    cmp.b     sync_shiftkeys(PC),d0
                    bne.l     end_sync
                    movem.l   d1/a0,-(SP)
                    lea       $ff820a,a0
                    move.b    video_sync_flag(PC),d0
                    beq       startresync
                    lea       video_sync_byte(PC),a0
!startresync        move.b    (a0),d0             ; Resynchronisation ausl”sen
                    move.b    d0,old_sync(A4)
                    move.w    sync_time_mono(PC),d1
                    move.b    $ff8260,d0
                    andi.b    #3,d0
                    cmpi.b    #2,d0
                    beq       starttoggle
                    tst.b     d0
                    beq       togglelowres
!togglemidres       btst.b    #1,(a0)             ; 50 od 60 Hertz
                    beq       togglemid60
!togglemid50        move.w    sync_time_mid50(PC),d1
                    bra       starttoggle
!togglemid60        move.w    sync_time_mid60(PC),d1
                    bra       starttoggle
!togglelowres       btst.b    #1,(a0)
                    beq       togglelow60
!togglelow50        move.w    sync_time_low50(PC),d1
                    bra       starttoggle
!togglelow60        move.w    sync_time_low60(PC),d1
!starttoggle
                    move.b    old_sync(A4),d0
                    eori.b    #1,d0               ; durch kurzfristiges in-
                    move.b    d0,$ff820a          ; vertieren des Bits f�r
                                                  ; interne bzw. externe
!do_nothing         dbra      d1,do_nothing       ; Synchronisation
                    move.b    old_sync(A4),d0
                    move.b    d0,$ff820a
                    movem.l   (SP)+,d1/a0
                    move.l    (sp)+,d0
                    bra       kill_key

!end_sync           move.l    (sp)+,d0            ; Registerrestaurierung
                    bra       return_ikbd         ; und zur�ck

!switch_intern      move.l    d0,-(sp)            ; Registersicherung
                    bsr       KbShift
                    andi.b    #$f,d0
                    cmp.b     sync_shiftkeys(PC),d0
                    bne       end_sync_int
                    clr.w     d0
                    bclr      d0,$ff820a
                    move.l    (sp)+,d0
                    bra       kill_key
end_sync_int        move.l    (sp)+,d0
                    bra       return_ikbd

!switch_extern      move.l    d0,-(sp)            ; Registersicherung
                    bsr       KbShift
                    andi.b    #$f,d0
                    cmp.b     sync_shiftkeys(PC),d0
                    bne       end_sync_ext
                    clr.w     d0
                    bset      d0,$ff820a
                    move.l    (sp)+,d0
                    bra       kill_key
end_sync_ext        move.l    (sp)+,d0
                    bra       return_ikbd

;
;
; MFP-Int. Routine f�r Keyboard-Entry
;
;
          ASC     'XBRA'
          ASC     'TMon'
chkKbd0   DC.L    0
ChkKbdEntry
          ; zuerst alten MFP-Handler aufrufen. Der wird mit RTE zur�ckkommen
          TST     StkFrm
          BEQ     chkKbd3
          MOVE    #$0010,-(A7)    ; Stackframe von Ill.Instr. laden
chkKbd3   pea     chkKbd2(PC)
          move    SR,-(A7)
          move.l  chkKbd0(PC),-(A7)
          RTS
chkKbd2   tst.b   CallFlag        ; bin ich aufgerufen worden ?
          beq     EndVBL
          sf      CallFlag        ; und Flag gleich wieder l”schen
          tas     MonActive
          bpl     startmon
          ;Trace-Abort-Flag setzen
          MOVE.L  A6,-(A7)
          MOVE.L  LocVarP(PC),A6
          BSET    #2,TrcStat(A6)     ; !!! stattdessen erst test, ob
                                     ; Tracebit in SR gesetzt, und nur,
          MOVE.L  (A7)+,A6           ; wenn gesetzt, dieses Bit setzen
!EndVBL   RTE

startmon  BSR.L   PULLREGS
          ; Interruptlevel zur�ck und Semaphore freigeben
          MOVE    SR,D1
          ANDI.W  #$FDFF,D1
          OR.W    IRMask(PC),D1
          MOVE    D1,SR

          BTST    #1,TrcStat(A4)     ; TraceMode on ?
          BEQ     EntKBDE1
          TST     TrcStat(A4)        ; just tracing ?
          BPL     EntKBDE1
          
          BSR     ResetBPs         ; BPs RšCKSETZEN
          
          MOVE.B  TrcStat(A4),D7
          BSET    #2,D7
          BRA     TrcC1
*)

(*$? AltHelp:
;
; Keyboard-Entry ( mit ALT/HELP )
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyKBD    BSR     KbShift            ; Shift oder Ctrl (Alt wird ja gedr�ckt) ?
          ANDI    #15,D0
          CMPI    #8,D0
          BNE     HardCopy

noCtlAhl  MOVE.L  LocVarP(PC),A6
          ;               BTST    #0,TrcStat(A6)
          BRA ENTKBDC0  ; BEQ     EntKBDC0 ; auf Tracebit d. SR testen

EntKbdE   BSET    #2,TrcStat(A6)     ; !!! stattdessen erst test, ob
                                     ; Tracebit in SR gesetzt, und nur,
          RTS                        ; wenn gesetzt, dieses Bit setzen

HardCopy  MOVE.L  A0,D0
          LEA     EyKBD(PC),A0
          MOVE.L  -4(A0),-(A7)
          MOVE.L  D0,A0
          RTS

EntKBDC0  TAS     MonActive
          BMI     EntKBDE

          ADDQ.L  #8,A7
!startmon
          MOVEM.L (A7)+,D0-A5
          MOVEM.L D0-A5,RgD0(A6)
          MOVE.L  A6,A4
          MOVE.L  (A7)+,RgA6(A4)
          MOVE.W  (A7)+,RgSR(A4)      ; SR VON STACK
          MOVE.L  (A7)+,RgPC(A4)      ; EXCEPTION-RETURN-ADR. VON STACK
          TST.W   is20(A4)
          BNE     is20_7
          CLR.B   RgPC(A4)
is20_7
          MOVE.L  A7,RgSSP(A4)        ; SP SAVEN
          MOVE.L  USP,A0
          MOVE.L  A0,RgUSP(A4)
          MOVE.L  MonStackHi(A4),A7

          BSR     SETMON

          ; Interruptlevel zur�ck und Semaphore freigeben
          SUBQ    #1,$4EE       ; _dumpflg r�cksetzen
          MOVE.W  #1,$452

          MOVE    SR,D1
          ANDI.W  #$FDFF,D1
          OR.W    IRMask(PC),D1
          MOVE    D1,SR

          BTST    #1,TrcStat(A4)     ; TraceMode on ?
          BEQ     EntKBDE1
          TST     TrcStat(A4)        ; just tracing ?
          BPL     EntKBDE1
          
          BSR     ResetBPs         ; BPs RšCKSETZEN
          
          MOVE.B  TrcStat(A4),D7
          BSET    #2,D7
          BRA     TrcC1
*)
EntKbdE1  LEA     KBDEMSG(PC),A1
          BRA     CMDBEG
;
; ASCII SPEICHER-EINGABE
;
!ComdHKOM BCLR    #11,D7
          BSR.L   GETADR0
          BMI     CHKEND
          MOVE.L  D1,LastIA(A4)
          MOVEA.L D1,A1
          CMPI.B  #SPC,D0
          BNE     ERR6
!CHKL1    ADDQ.L  #1,A6
          MOVE.B  (A6),D0
          CMPI.B  #CR,D0
          BEQ     CHKEND
          MOVE.B  D0,(A1)+
          BRA.L   CHKL1
          
!CHKEND   RTS
;
; ASCII SPEICHER-ANZEIGE
;
!ComdI    LEA     LastIA(A4),A1   ; LETZTE ANF.ADR. ALS DEFAULT-WERT-POINTER
          BSET    #12,D7          ; Ungerade Adr. erlaubt
          BSR.L   GETAE           ; ANF.-/END- ADR. NACH A2/A3 HOLEN
          BPL     ERR4
          MOVEQ   #ADUMPANZ-1,D6  ; ANZ. bytes -1 PRO ZEILE
!CIL1     BSR     PrtPRMPT
          MOVEQ   #ASCPRMPT,D0
          BSR     Prt
          MOVE.L  A2,D0           ; PRINT ADRESSE
          BSR     PrtADR
          BSR     PrtSPC
          MOVE.W  D6,D5
          
          BSR.L   CIU
          
          BSR.L   TSTKEY
          BNE     CIEND
          ;Warteschleife f. 68020
          BSR     DelayIf20
          BTST    #1,D7
          BEQ     CIC1
          SUBQ.L  #1,D3
          BNE     CIL1
          BRA.S   CIEND
!CIC1     CMPA.L  A3,A2
          BCS     CIL1
!CIEND    MOVE.L  A2,LastIE(A4)
          RTS
;
; DRUCKER ANSTEUERUNG
;
CmdPFF    MOVEQ   #FF,D0
          BRA     Prt
          
PrOpE0    TST     D3
          BEQ     PrOpE1
          LEA     ProtMsg(PC),A1
          BSR     PrtStr
          LEA     ClosMsg(PC),A1
          BRA     PrtStr
PrOpE1    RTS

!ComdP    BSR     SkipSpc
          BMI     CmdPFF
          
          MOVE    D0,D2
          MOVE    PrHandle(A4),D3
          BEQ     PrNotOp
          BSR     PrtCRLF
PrNotOp   BSR.L   PrntClose     ; Printerfile schliežen
          BCLR    #11,D7
          BSR     GetNGRKL
          SUBQ.L  #1,A6
          BPL     PrOpC0
          CMPI.B  #'C',D2
          BEQ     PrOpE0        ; Ende
PropC0    CLR     -(A7)
          MOVE.L  A6,-(A7)
PropL0    BSR.L   GETNGRKL
          BPL     PropL0
          CLR.B   (A6)       ; String mit Null abschliessen
          CMPA.L  (A7),A6
          BEQ     ERR9          ; ERROR: FEHLENDER NAME
          
          CMPI.B  #':',-1(A6)   ; Filename = 'xxx:' ?
          BEQ     PropC1
          MOVE    #$3C,-(A7)    ; Fcreate
          BRA     PropC2
PrOpC1    MOVE    #$3D,-(A7)    ; Fopen
          MOVE    #1,6(A7)      ; mode = WriteOnly
PrOpC2    TRAP    #1
          ADDQ.L  #8,A7
          TST.L   D0
          BMI     PrntCloseErr
          TST     D0
          BPL     PrOpC3
          NEG     D0
PrOpC3    MOVE    D0,-(A7)
          LEA     ProtMsg(PC),A1
          BSR     PrtStr
          LEA     OpMSG(PC),A1
          BSR     PrtSTR
          MOVE    (A7)+,PrHandle(A4)
          RTS
          
LSCloseErr  ; in D0 steht Fehlernummer !
          MOVE.L  MemAdr(A4),D1
          BEQ     noMFree1
          CLR.L   MemAdr(A4)
          MOVE    D0,-(A7)
          MOVE.L  D1,-(A7)
          MOVE    #$49,-(A7)
          TRAP    #1                    ; MFREE
          ADDQ.L  #6,A7
          MOVE    (A7)+,D0
noMFree1  MOVE    RWhandle(A4),D1
          CLR.W   RWhandle(A4)
          BRA     PLSClsErr

PrntCloseErr  ; in D0 steht Fehlernummer !
          MOVE    Prhandle(A4),D1
          CLR.W   PrHandle(A4)

PLSClsErr MOVE.W  D0,-(A7)
          BSR     PLSClose
          MOVE.W  (A7)+,D2
          BPL     PLSClsE0              ; kein Error, dann keine Ausgabe
          LEA     IOResMsg(PC),A1       ; (tritt auf, wenn von Printerror
          BSR     PrtSTR                ;  aufgerufen wird)
          MOVE.W  D2,D0
          NEG     D0
          BRA     PrtByte
PLSClsE0  BRA     PrtCRLF
          
LSClose   MOVE    RWhandle(A4),D1
          CLR.W   RWhandle(A4)
          BRA     PLSClose

PrntClose MOVE    Prhandle(A4),D1
          CLR.W   PrHandle(A4)
          
PLSClose  CMPI    #5,D1
          BLS     PLSCLE1
          MOVEM.L D2-A6,-(A7)
          MOVE    D1,-(A7)
          MOVE    #$3E,-(A7)
          TRAP    #1
          ADDQ.L  #4,A7
          MOVEM.L (A7)+,D2-A6
PLSCLE1   RTS
;
;
; LOAD / SAVE
;
noLMem    LEA     noMemMsg(PC),A1
          BSR     PrtStr
          BRA     LSClose
          
LSOpen    BCLR    #11,D7
          BSR.L   SKIPSPC
          BMI     ERR9            ; ERROR: FEHLENDER NAME
          
          MOVE.L  A6,-(A7)
LSopL0    CMPI.B  #',',D0
          BEQ.S   GETLSPC1
          BSR.L   GETNGRKL
          BMI.S   GETLSPC1
          CMPI.B  #' ',D0
          BNE     LSopL0
!GETLSPC1 CLR.B   (A6)       ; Strings mit Null abschliessen
          CMPA.L  (A7),A6
          BEQ     ERR9          ; ERROR: FEHLENDER NAME
          
          BSET    #12,D7          ; Ungerade Adr. erlaubt
          CLR.L   MemAdr(A4)
          CLR.L   FileStart(A4)
          SF      OverWrite(A4)
          
          BSR     GETNGRKL
          BSR.L   SKIPSPC
          BMI.L   LSopE0
          CMPI.B  #relFchr,D0
          BNE     LSopC2
          BSR     GETNGRKL
          BSR     GetLongX
          MOVE.L  D1,FileStart(A4)
          ST      OverWrite(A4)
          BSR.L   SKIPSPC
          BMI     LSopE0
          CMPI.B  #',',D0
          BNE     Err11
          BSR     GETNGRKL
LSopC2    LEA     Hilf1L(A4),A1
          BSR     GETAE
LSopE0    MOVEA.L (A7)+,A1
          RTS
;
LSeek     MOVE.L  A2,-(A7)
          MOVE    D0,-(A7)        ; mode (0:from begin, 2:from end)
          MOVE    RWhandle(A4),-(A7)
          MOVE.L  D1,-(A7)        ; pos.
          MOVE    #$42,-(A7)
          TRAP    #1
          ADDA.W  #10,A7
          MOVE.L  (A7)+,A2
          TST.L   D0
          BMI     LSCloseErr
          RTS
;
!ComdL    CMPI.B  #'-',D0
          BNE     CmdLC0
          BSR     GetNGrKl
          BCLR    #12,D7          ; nur gerade adr.
          BSR     GetAdrG
          BPL     ERR4
          MOVE.L  D1,-(A7)
          MOVE    #$49,-(A7)
          TRAP    #1                    ; MFREE
          ADDQ.L  #6,A7
          BCLR    #11,D7
          TST.L   D0
          BEQ     disposed
          LEA     notAllocMsg(PC),A1
          BRA     PrtStr
disposed  LEA     OKMsg(PC),A1
          BRA     PrtStr
          
CmdLC0    BSR     LSOpen
          MOVE.L  A2,-(A7)
          CLR     -(A7)
          MOVE.L  A1,-(A7)
          MOVE    #$3D,-(A7)      ; Open
          TRAP    #1
          ADDQ.L  #8,A7
          MOVE.L  (A7)+,A2
          TST     D0
          BMI     LSCloseErr
          MOVE    D0,RWhandle(A4)
          
          ; Dateil„nge ermitteln:
          MOVEQ   #2,D0
          MOVEQ   #0,D1
          BSR     LSeek
          MOVE.L  D0,FileLen(A4)
          MOVEQ   #0,D0
          MOVE.L  FileStart(A4),D1
          BSR     LSeek
          
          MOVE.L  FileLen(A4),D1
          SUB.L   FileStart(A4),D1      ; D1:= zu lesende Menge
          MOVE.L  D1,MemLen(A4)
          
          BTST    #2,D7
          BNE     LhasAdr
          
          ; Wenn keine Anf.Adr, dann wird Speicher angefordert.
          MOVE.L  A2,-(A7)
          MOVE.L  D1,-(A7)
          MOVE    #$48,-(A7)
          TRAP    #1                    ; Malloc
          ADDQ.L  #6,A7
          MOVE.L  (A7)+,A2
          TST.L   D0
          BEQ     noLMem
          BMI     noLMem
          MOVE.L  D0,A2                 ; Anfangsadr. zum Laden
          MOVE.L  D0,MemAdr(A4)
          
LhasAdr   BTST    #3,D7
          BNE     LhasAdr2              ; Endadr. angegeben ?
          MOVE.L  A2,A3
          ADDA.L  MemLen(A4),A3         ; A3 auf A2+L„nge
          
LhasAdr2  LEA     LoadMSG(PC),A1
          BSR     PrtSTR
          MOVE.L  A2,D0
          BSR     Prtlong
          
          MOVE.L  A3,-(A7)
          MOVE.L  A2,-(A7)
          SUBA.L  A2,A3
          MOVE.L  A3,-(A7)
          MOVE    RWhandle(A4),-(A7)
          MOVE    #$3F,-(A7)            ; FREAD
          TRAP    #1
          ADDQ.L  #8,A7
          MOVE.L  (A7)+,A2
          MOVE.L  (A7)+,A3
          TST.L   D0
          BMI     LSCloseErr
          
          CLR.L   MemAdr(A4)
          BSR     LSClose         ; Fehler kann nicht auftreten
          LEA     ENDMSG(PC),A1
          BSR     PrtSTR
          MOVE.L  A3,D0
          BRA     Prtlong
;
!ComdS    BSR     LSOpen
          BTST.L  #3,D7
          BEQ     ERR11           ; ERROR: BEIDE ADR. ANGEBEN !
          MOVE.L  A2,-(A7)
          TST     OverWrite(A4)
          BEQ.S   doCreate
          MOVE    #1,-(A7)
          MOVE.L  A1,-(A7)
          MOVE    #$3D,-(A7)      ; Open
          BRA.S   CmdSC0
doCreate  CLR     -(A7)
          MOVE.L  A1,-(A7)
          MOVE    #$3C,-(A7)      ; Create
CmdSC0    TRAP    #1
          ADDQ.L  #8,A7
          MOVE.L  (A7)+,A2
          TST     D0
          BMI     LSCloseErr
          MOVE    D0,RWhandle(A4)
          
          MOVEQ   #0,D0
          MOVE.L  FileStart(A4),D1    ; an die Startposition seeken
          BSR     LSeek
          
          LEA     SAVEMSG(PC),A1
          BSR     PrtSTR
          MOVE.L  A2,D0
          BSR     Prtlong
          
          MOVE.L  A3,-(A7)              ; Endadr. retten
          MOVE.L  A2,-(A7)              ; Datenadr.
          SUBA.L  A2,A3
          MOVE.L  A3,-(A7)              ; Anzahl
          MOVE    RWhandle(A4),-(A7)
          MOVE    #$40,-(A7)            ; Write
          TRAP    #1
          ADDQ.L  #8,A7
          MOVE.L  (A7)+,A2
          MOVE.L  (A7)+,A3
          TST.L   D0
          BMI     LSCloseErr
          
          BSR     LSClose
          TST.W   D0
          BMI     LSCloseErr
          LEA     ENDMSG(PC),A1
          BSR     PrtSTR
          MOVE.L  A3,D0
          BRA     Prtlong
;
;
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
!EyCritic MOVEQ   #-1,D0
          RTS
;
; DISASSEMBLER F. EINE ZEILE, ADR. IN A2
;
!DISASMLN BSR     PrtPRMPT
          MOVEQ   #',',D0
          BSR     Prt

!DISASM   MOVEM.L D0-A1/A3-A6,-(A7)
          MOVEA.L A2,A1

          (*$I .\DISM20.ICL *)

          MOVEA.L A1,A2
          MOVEM.L (A7)+,D0-A1/A3-A6
          RTS
;
;         ****  Neue MIDI-KEYBOARD IRQ-ROUTINE  ****
(*$? ADC:
          ASC     'XBRA'
          ASC     'TMon'
          DC.L    0
NKeyMidi: movem.l   d0-d3/a0-a3/a5,-(sp)
          suba.l    a5,a5               ; A5 l”schen
keyirql0  move.l    IKBDSYSV(pc),a2     ; Adresse der alten Keyb.-Systemrout.
          jsr       (a2)                ; Taste abholen
          btst.b    #4,$FFFFFA01        ; Noch eine ?
          beq.s     keyirql0            ; Ja
          bclr      #6,$FFFFFA11
          movem.l   (sp)+,d0-d3/a0-a3/a5
          rte                           ; }
;-------------------
*)

;         ****  MONITOR-VECTOR INITIALISIERUNG  ****
;
;
ChgVec    ; Vektor neu setzen und ggf. (wenn D0<>0) anzeigen
          ; A0: Entryadr. (mit XBRA-Vorsatz), A1: Vektoradr.
          TST.W   is20(A4)
          BNE     is20_8
          CLR.B   (A1)
is20_8
          CMPA.L  (A1),A0            ; ist noch Templemon-Vektor?
          BEQ     ChgNoVec
          TST.W   D0
          BEQ     ChgVec0
          MOVEM.L D0/A0/A1,-(A7)
          BSR     PrtCRLF
          LEA     vecmsg1(PC),A1
          BSR     PrtStr
          MOVE.L  8(A7),D0           ; A1
          BSR     PrtAdr             ; print Vektor-Adr
          LEA     vecmsg2(PC),A1
          BSR     PrtStr
          MOVE.L  8(A7),A0           ; A1
          MOVE.L  (A0),D0
          BSR     PrtAdr             ; print old vector value
          MOVEM.L (A7)+,D0/A0/A1
ChgVec0   MOVE.L  (A1),-4(A0)        ; alten Vektor sichern
          MOVE.L  A0,(A1)
ChgNoVec  RTS

; Parameter: D0: 1->Žnderungen anzeigen; D1: 1->alle Traps setzen
InitVec   LEA     EyBUS(PC),A0
          LEA     BUSERRV,A1
          BSR     ChgVec

          LEA     EyADR(PC),A0
          LEA     ADRERRV,A1
          BSR     ChgVec

          LEA     EyTRC(PC),A0
          LEA     TraceV,A1
          BSR     ChgVec

          TST     isTT(A4)
          BNE     noPrivInst
          LEA     EyPRIV(PC),A0
          LEA     PRIVV,A1
          BSR     ChgVec
noPrivInst
          LEA     EyDIV(PC),A0
          LEA     DIVZV,A1
          BSR     ChgVec

          LEA     EyCHK(PC),A0
          LEA     CHKV,A1
          BSR     ChgVec

          LEA     EyTRAPV(PC),A0
          LEA     TRAPVV,A1
          BSR     ChgVec

          LEA     EyILL(PC),A0
          LEA     ILLCMDV,A1
          BSR     ChgVec

          LEA     EyFrm(PC),A0
          LEA     FRMERRV,A1
          BSR     ChgVec

          LEA     EyILLIRQ(PC),A0
          LEA     ILLIRQV,A1
          BSR     ChgVec

          LEA     EyDirC(PC),A0
          LEA     IRQ1V,A1
          BSR     ChgVec

          LEA     EyIRQ(PC),A0
          LEA     IRQ3V,A1        ; IRQ NO.3 EXCEPTION VEKTOR
          BSR     ChgVec
          LEA     IRQ5V,A1        ; IRQ NO.5 EXCEPTION VEKTOR
          BSR     ChgVec
          LEA     IRQ7V,A1        ; NMI
          BSR     ChgVec

          LEA     EyTRAP0(PC),A0     ; TRAP #6
          LEA     Trap6V,A1
          BSR     ChgVec

          TST.L   D1
          BEQ     noMoreTraps
          LEA     Trap0V,A1
          BSR     ChgVec
          LEA     Trap3V,A1
          BSR     ChgVec
          ADDQ.L  #4,A1
          BSR     ChgVec        ; 4
          ADDQ.L  #4,A1
          BSR     ChgVec        ; 5
          ADDQ.L  #8,A1
          BSR     ChgVec        ; 7
          ADDQ.L  #4,A1
          BSR     ChgVec        ; 8
          ADDQ.L  #4,A1
          BSR     ChgVec        ; 9
          ADDQ.L  #4,A1
          BSR     ChgVec        ; 10
          ADDQ.L  #4,A1
          BSR     ChgVec        ; 11
          ADDQ.L  #4,A1
          BSR     ChgVec        ; 12
          ADDA.W  #12,A1
          BSR     ChgVec        ; 15
noMoreTraps

(*$? AltHelp:
          LEA     EyKBD(PC),A0
          LEA     $502,A1
          BSR     ChgVec
*)
          TST     StkFrm
          BNE     noSetMSB
          ;MSBytes der Vektoren 2-63 (und MFP-Vektoren) neu setzen
          MOVEQ   #2,D0
SETMSBY   MOVE.L  D0,A0
          ADDA.L  A0,A0
          ADDA.L  A0,A0
          MOVE.B  D0,(A0)
          ADDQ.W  #1,D0
          CMPI    #64+16,D0
          BCS     SETMSBY
noSetMSB  RTS

stackframe_Test:
          MOVE.L  A7,D2
          MOVE.L  $10,D1  ; Illegal Instruction Exc-Vektor
          LEA     stackfrb(PC),A0
          MOVE.L  A0,$10
          DC.W    $4AFC   ; ILLEGAL
stackfrb  MOVE.L  A7,D0
          MOVE.L  D2,A7
          ADDQ.L  #6,D0
          CMP.L   D0,D2
          SNE     D0
          ANDI    #2,D0
          MOVE.W  D0,StkFrm   ; = 0 bei 68000, = 2 ab 68010
          MULU    #3,D0
          MOVE.W  D0,StkFrTrc(A4)  ; = 6 ab 68010
          MOVE.L  D1,$10
          RTS

outchar:  MOVEM.L D0-D7/A0-A6,-(A7)
          MOVE    D0,-(A7)
          MOVE    #2,-(A7)
          MOVE    #3,-(A7)
          TRAP    #13
          ADDQ.L  #6,A7
          MOVE    #2,-(A7)
          MOVE    #2,-(A7)
          TRAP    #13
          ADDQ.L  #4,A7
          MOVEM.L (A7)+,D0-D7/A0-A6
          RTS

;***************************************************************************
; Routinen zum Unterbrechen und Wiederaufnahmen des Datentransportes zwischen
; ST und IKBD. Keine Interruptsperrung !!!, sonst gibt's nen H„nger !!!,
; nur im Supervisormodus nutzen, sonst gibt's nen Buserror !!!.

!Wr_IKBD  MOVEM.L D2/A0,-(SP)             ; Write Char in D0 an IKBD
          LEA     $FFFC00,A0              ; Keyboard ACIA Control Register
acia_status
          MOVE.B  (A0),D2                 ; ACIA Statusregister lesen
          BTST.L  #1,D2                   ; Sender bereit?
          BEQ     acia_status             ; nein warten
          MOVE.W  #950,D2
verzoeger
          BSR.B   verzoeger_tail
          DBF     D2,verzoeger
          MOVE.B  D0,2(A0)
          MOVEM.L (SP)+,D2/A0
verzoeger_tail
          RTS

!Pause_IKBD
          MOVE.B  #$13,D0
          BRA     Wr_IKBD

!Resume_IKBD
          MOVE.B  #$11,D0
          BRA     Wr_IKBD

;#################################################################
;
; Testet die gerade aktuelle Aufl”sung. Das Ergebnis wird in D0 abgelegt.
; Overscanmodus : D0 = -1L
; Normalmodus   : D0 = 0L

OverScanTest: move.l    d1,-(SP)
              bsr       Pause_IKBD
              move.w    SR,-(Sp)
              move.w    #$2700,SR
              move.b    $FF8203,d0
              move.b    d0,d1                   ; Overscan-Modus testen
              addi.b    #$7d,d1
VWait1:       cmp.b     $FF8207,d1
              bne       VWait1
VWait2:       cmp.b     $FF8207,d1
              beq       VWait2
              cmp.b     $FF8207,d0
              beq       ONot
              move.w    (SP)+,SR
              bsr       Resume_IKBD
              move.l    (SP)+,d1
              moveq.l   #-1,d0
              rts
ONot:         move.w    (SP)+,SR
              bsr       Resume_IKBD
              move.l    (SP)+,d1
              clr.l     d0
              rts

;#################################################################
;
!BigScreen
          MOVEM.L A1/D0,-(SP)
          MOVE.B  #$D6,$FFFC00
          LEA     $FF8200,A1
          MOVEP.W 1(A1),D0
          BSR     Wvbl
          MOVEM.L (SP)+,A1/D0
          RTS

!SmallScreen
          MOVEM.L A1/D0,-(SP)
          MOVE.B  #$96,$FFFC00
          LEA     $FF8200,A1
          MOVEP.W 1(A1),D0
          BSR     Wvbl
          MOVEM.L (SP)+,A1/D0
          RTS

!GetMonoConst
          MOVE.L        D0,-(SP)
	      MOVE.W        #16,CharHeight(A4)
          MOVE.W        #1,video_plane(A4)
          MOVE.W        m_VideoBytes(PC),D0
          MOVE.W        D0,video_line_bytes(A4)
          MOVE.L        m_VideoMemory(PC),D0
          MOVE.L        D0,video_memory(A4)
          MOVE.L        tmon_offset_mon(PC),D0
          MOVE.L        D0,tmon_offset(A4)
          MOVE.L        (SP)+,D0
          RTS

!GetColorConst
          MOVE.L        D0,-(SP)
          MOVE.W        #8,CharHeight(A4)
          MOVE.W        #2,video_plane(A4)
          MOVE.W        c_VideoBytes(PC),D0
          MOVE.W        D0,video_line_bytes(A4)
          MOVE.L        c_VideoMemory(PC),D0
          MOVE.L        D0,video_memory(A4)
          MOVE.L        tmon_offset_col(PC),D0
          MOVE.L        D0,tmon_offset(A4)
          MOVE.L        (SP)+,D0
          RTS

;*****************************************************************

saveCodeLen DS    4
oldSP       DS    4

;*****************************************************************

; ST,STE oder TT Mittels CookieJar abpr�fen

!MCH_Test MOVEM.L A0/D0,-(SP)
          CLR.W   isTT(A4)
          CLR.W   isSTE(A4)
          MOVE.L  $5A0,A0  ; CookiePointer
          MOVE.L  A0,D0
          BEQ     MCH_Stop       ; kein CookieJar
          BRA     MCH_Strt
!MCH_Loop ADDQ.L  #4,A0
!MCH_Strt TST.L   (A0)
          BEQ     MCH_Stop       ; Ende der Liste
          CMPI.L  #$5F56444F,(A0)+ ; Vergleich auf '_VDO'
          BNE     MCH_Loop
          MOVE.W  (A0),D0
          BEQ     MCH_Stop        ; ST gefunden
          CMPI.W  #$1,D0
          BEQ     STE_found       ; STE gefunden
          CMPI.W  #$2,D0
          BNE     MCH_Stop        ; was unbekanntes gefunden: wie ST behandeln!
          MOVE.W  #2,isTT(A4)
          BRA     MCH_Stop
!STE_found ST     isSTE(A4)
!MCH_Stop MOVEM.L (SP)+,A0/D0
          RTS


!INITGMON MOVE.L  4(A7),A5        ; Ptr auf base page laden
          ; Supervisormodus:
          CLR.L   -(A7)
          MOVE.W  #$20,-(A7)
          TRAP    #1
          ADDQ.L  #6,A7
          LEA     OldSP(PC),A0
          MOVE.L  D0,(A0)
          
          LEA     EyIRQ(PC),A0
          MOVE.L  -8(A0),D0     ; 'TMon' nach D0
          MOVE.L  IRQ7V,A0
          CMP.L   -8(A0),D0     ; steht 'TMon' in XBRA-Kennung?
          BEQ.W   noInstall
          
          MOVE.W  #-1,-(SP)
          MOVE.W  #$B,-(SP)
          TRAP    #13
          ADDQ.L  #4,SP
          CMP.B   abort_key_mask(PC),D0
          BEQ.W   noInstall

          LEA     pBasePage(PC),A0
          MOVE.L  A5,(A0)

          MOVE.L  codelen(A5),D0
          ADDI.L  #256,D0               ; base page
          ADD.L   datalen(A5),D0
          ADD.L   bsslen(A5),D0         ; Platz f. globale Variable

          MOVE.L  D0,D1
          ADD.L   A5,D1
          LEA     LocVarP(PC),A0
          MOVE.L  D1,(A0)               ; bss liegt hinter code
          MOVE.L  D1,A4                 ; wird gleich noch gebraucht

          LEA     LBLBEG(A4),A0
          LEA     LblEnd(A4),A6
!ECLDL1   CLR.W   (A0)+           ; ALLE MON-VARIABLEN LOESCHEN
          CMPA.L  A6,A0
          BCS     ECLDL1

          SF      MonActive
          BSR     MCH_Test

          ADDI.L  #LastLocalVar,D0      ; Platz f. lokale Variable
          ANDI.W  #$FFFE,D0
          ADDQ.L  #2,D0

          MOVE.L  D0,-(SP)
          MOVE.B  edit_modus(PC),D0
          EXT.W   D0
          MOVE.W  D0,EditModus(A4)
          CLR.W   autoswitch(A4) ; erst mal mit keinem AutoSwitch belegen
          CLR.W   video_modus(A4)
          BSR     GetMonoConst          ; Mono Hyperscreen video Daten

          BSR     stackframe_Test       ; CPU-Test
          
          MOVE    StkFrm,is20(A4)       ; Bei 680x0 wird 68020 angenommen!!!
          
          TST     StkFrm
          BEQ     noNewRate
          LEA     BlinkRate(PC),A0
          MOVE.L  (A0),D0
          LSL.L   #2,D0
          MOVE.L  D0,(A0)               ;Cursor-Blinken vierfach langsamer
noNewRate
          TST     isTT(A4)
          BNE     noAutoSwitch1
          TST     isSTE(A4)
          BNE     noAutoSwitch

          BSR     OverScanTest
          MOVE.W  D0,entry_video_modus(A4)
          MOVE.W  D0,video_modus(A4)
          BEQ     mustbeauto            ; kleiner Bildschirm, dann AutoSwitch OverScan
                                        ; oder normaler ST
          BSR     SmallScreen
          BSR     OverScanTest
          CMP.W   entry_video_modus(A4),D0
          BEQ     noAutoSwitch
          BSR     BigScreen
mustbeauto
          NOT.W   autoswitch(A4)
          CLR.W   video_modus(A4)
noAutoSwitch
          BTST.B  #1,$FF8260  ; Farbe ?
          BNE     noAutoSwitch1
          BSR     GetColorConst
noAutoSwitch1
          MOVE.L  (SP)+,D0
          ADD.L   A5,D0
          LEA     HistoryStart(PC),A0
          MOVE.L  D0,(A0)           ; HistoryStart
          MOVE.L  D0,8(A0)          ; HistoryAktuell
          MOVE.L  D0,12(A0)         ; HistorySuchen
          MOVE.L  D0,16(A0)         ; HistoryFill
          CLR.L   D2
          MOVE.B  edit_lines(PC),D2
          MULU    #80,D2
          ADD.L   D2,D0
          LEA     HistoryEnde(PC),A0
          MOVE.L  D0,(A0)

          ; Stack-Bedarf dazurechnen (hinter Screen legen):
          ADD.L   StackSize(PC),D0
          MOVE.L  D0,MonStackHi(A4)

          ; gesamte belegte Bytes des Programms sichern
          LEA     saveCodeLen(PC),A0
          SUB.L   A5,D0
          MOVE.L  D0,(A0)

          ; Speicherbereich verk�rzen
          MOVE.L  D0,-(SP)  ; Mshrink
          MOVE.L  A5,-(SP)
          CLR.W   -(SP)
          MOVE.W  #$4A,-(SP)
          TRAP    #1
          LEA     $C(SP),SP

          ; Bereich f. Mon-Screen reservieren :
          MOVE.L  #$8000,D0
          TST     isTT(A4)
          BEQ     Malloc
Mxalloc   CLR.W   -(SP)   ; ST Ram only!
          MOVE.L  D0,-(SP)  ; Mxalloc
          MOVE.W  #$44,-(SP)
          TRAP    #1
          ADDQ.L  #8,SP
          BRA     SetMallocReturn
Malloc    TST     isSTE(A4)  ; Malloc
          BNE     ScreenAllocate
          TST     autoswitch(A4)
          BNE     ScreenAllocate
          TST     entry_video_modus(A4)
          BEQ     ScreenAllocate
          MOVE.L  video_memory(A4),D0
          ADD.L   #256,D0               ; 256 Bytes Reserve
          ST      video_modus(A4)
ScreenAllocate
          ADDI.L  #256,D0
          MOVE.L  D0,-(SP)
          MOVE.W  #$48,-(SP)
          TRAP    #1
          ADDQ.L  #6,SP
SetMallocReturn
          TST.L   D0
          BEQ.L   noInstall
          ADDI.L  #255,D0
          ANDI.W  #$FF00,D0
          LEA     pMonScreen(PC),A0
          MOVE.L  D0,(A0)
          LSR.L   #8,D0
          LEA     rMonScreen(PC),A0
          MOVE.W  D0,(A0)

          move.w  #kbdvbase,-(sp)
          trap    #14
          addq.l  #2,sp
          move.l  d0,Kbdv_base

(*$ ? ExtendedKeys:
          clr.w   CallFlag
          st      LockFlag
          
          move.w  #1,-(sp)
          move.w  #$e,-(sp)
          trap    #14
          addq.l  #4,sp
          move.l  d0,IorecPointer
*)

          MOVEQ   #0,D0              ; InitVec: Žnderungen nicht anzeigen
          MOVEQ   #1,D1              ; InitVec: alle TRAPs setzen
          BSR     InitVec

          CLR.L   UsrBPV

          MOVEQ   #-1,D0
          BCLR    #TNRBER,D0
          BCLR    #TNRAER,D0
          MOVE.L  D0,RegWahl(A4)  ; REG.AUSWAHL:ALLE REGS bis auf BEV u. AEV
          
          ; Adr. der KbShift-Var. ermitteln
          MOVE.L    $4f2,A1
          MOVE.W    #$E1B,A0
          CMPI.W    #$0100,2(A1)        ; tos 1.0 ?
          BEQ       takeE1B             ; dann kennen wir die Adr.
          MOVE.L    $24(A1),A0          ; sonst holen wir Adr. aus TOS-Header
takeE1B   LEA       KbshiftV(PC),A1     ; Keyboard-Status-Adresse
          MOVE.L    A0,(A1)             ; sichern
          
          ;*** ^ auf Fontdaten holen:
          DC.W    $A000
          (*
          LEA     pFont6_6(PC),A2
          MOVE.L  (A1)+,A0      ; f. System-Font 6*6 (Icon)
          MOVE.L  76(A0),(A2)
          *)
          ADDQ.L  #4,A1
          LEA     pFont8_8(PC),A2
          MOVE.L  (A1)+,A0      ; f. System-Font 8*8 (Farbe)
          MOVE.L  76(A0),(A2)
          LEA     pFont8_16(PC),A2
          MOVE.L  (A1)+,A0      ; f. System-Font 8*16 (S/W)
          MOVE.L  76(A0),(A2)
          
          (*
          LEA     FontMode(PC),A0
          MOVE    #1,(A0)
          MOVE    #106,Rows(A4)  ;!!!
          MOVE    #66,Lines(A4)  ;!!!
          *)
          MOVE    #080,Rows(A4)
          MOVE    #25,Lines(A4)
          
          BSR     ClearScrn
          BSR     InitKeyBuf
          BSR     InitHistory

          ; Zeiger auf Tastatur-Puffer-Datensatz holen      ADC: {
          move.l    #$000e0001,-(sp)    ; Iorec
          trap      #14
          addq.l    #4,sp
          lea       KeyIORcV(pc),a0
          move.l    d0,(a0)      ; Zeiger auf Systemtastatur-Buf. speichern }

(*$ ? ExtendedKeys:
          ; Routine hinter Tastaturauswertung im IR-Level 6 h„ngen
          LEA       ChkKbdEntry(PC),A0
          MOVE.W    #$100+6*4,A1    ; MFP, Int-Nr. 6
          MOVE.L    (A1),-4(A0)     ; alten Vektor in XBRA merken
          MOVE.L    A0,(A1)
          ; Neuen IKBDSYS einbauen
          move.l    Kbdv_base,a0        ; Keyboard Basisadresse
          lea       EyIKBDSYS(PC),a1
          move.l    32(a0),-4(a1)
          move.l    a1,32(a0)
*)

          ; zur�ck in den User-Modus
          MOVE.L  OldSP(PC),-(A7)
          MOVE.W  #$20,-(A7)
          TRAP    #1
          ADDQ.L  #6,A7

(*$? ADC:
          ; Adresse der TOS Tasten-Verarbeitungs Routine holen ADC: {
          move.w    #kbdvbase,-(sp)           ; Adresse der Vectortabelle holen
          trap      #14
          addq.l    #2,sp
          move.l    d0,a0
          lea       IKBDSYSV(pc),a1
          move.l    32(a0),(a1)         ; Keyboard-System-Routine sichern }
*)

          ; Init-Msg ausgeben
          PEA     initMsg(PC)
          MOVE.W  #$09,-(A7)
          TRAP    #1
          ADDQ.L  #6,A7

(*$? ExtendedKeys:
          sf      LockFlag
*)

          ; Nun wird GEMDOS $31 aufgerufen (Keep process)
          CLR.W   -(A7)
          MOVE.L  saveCodeLen(PC),-(A7)
          MOVE.W  #$31,-(A7)
          TRAP    #1

noInstall PEA     noInstallMsg(PC)
          MOVE.W  #9,-(SP)
          TRAP    #1
          ADDQ.L  #6,SP

noInstall1 ; zur�ck in den User-Modus
          MOVE.L  OldSP(PC),-(A7)
          MOVE.W  #$20,-(A7)
          TRAP    #1
          ADDQ.L  #6,A7

          CLR     -(A7)
          TRAP    #1      ; Pterm0
!EndOfMon
END;                      (* ENDE ASSEMBLER *)

END MONITOR;

BEGIN
  ASSEMBLER
          JMP     MONITOR
  END;                    (* ENDE ASSEMBLER *)
END TEMPLMON.
