; Name      : Select
; Funktion  : Programme in abhängigkeit von der Version des Betriebssystems
;             starten
; Aufruf    : Select VERSION/A PROGRAMM/A
; Kickstart : 1.x, OS 2.x
; Test unter: Kickstart 1.2, OS 2.04
; Assembler : MaxonAsm V1.1
; Copyright : (PD) August, 1992 by Indy


; Autor             Datum       Bemerkung
;---------------------------------------------------------
; Indy              19-Aug-1992 MaxonAsm V1.1



  MC68000                     ; Angabe des Prozessor für MaxonAsm

  INCDIR    "MaxonAsm:Includes"
  INCLUDE   "lvo.i"
  INCLUDE   "Exec/Libraries_Mac.i" ; Eigenes File (müßte auf Disk sein)
  INCLUDE   "Exec/Libraries.i"
  INCLUDE   "Dos/Dos.i"
  INCLUDE   "Utility/TagItem.i"
;---------------------------------------------------------------

SysBase           = 4
_LVOSystem        = -606      ; OS 2.04
;---------------------------------------------------------------

; Fkt: Register auf Stack retten
; Ein: - Register (wie bei movem.l)

MPush MACRO
  movem.l \1,-(sp)
  ENDM
;-----------------------------

; Fkt: Register von Stack holen
; Ein: - Register (wie bei movem.l)

MPull MACRO
  movem.l (sp)+,\1
  ENDM
;---------------------------------------------------------------


; Fkt: Fehlermeldung ausgeben und nach End_Error verzweigen.
; Ein: - Text der Fehlermeldung in Anführungszeichen

MDosErr: MACRO
   lea      Error\@,a0
   bsr      Print_0
   bra      End_Error

   SECTION  "DATA", DATA
Error\@: dc.b "\1",10,0
   EVEN
   SECTION  "CODE", CODE

   ENDM
;---------------------------------------------------------------
  SECTION   "CODE", CODE

Start:
  MPush     d2/a2/a6

  movea.l   a0,a2             ; a2.l -> ^Cli Argument
  move.l    d0,d2             ; d2.l -> Länge vom Cli Argument

  MOpenLib  "dos",DosBase,33  ; Dos-Library öffnen
  tst.l     d0
  beq       End_Error         ; Fehler -> End_Error

  movea.l   a2,a0             ; a0.l -> ^Cli Argument
  clr.b     -1(a0,d2.l)       ; Linefeed durch null ersetzen

Parse_It:
  bsr       Skip_Space        ; Spaces überspringen
  tst.b     (a0)              ; Eingabe vorhanden ?
  beq       End               ; Nein -> End
  cmpi.b    #"?",(a0)         ; Help ?
  beq       Help              ; Ja -> Help

  movea.l   a0,a2             ; a0.l in a2.l retten
  bsr       Get_Dec           ; d0.l -> Versionsnummer, d1.l -> Anzahl Zch
                              ;                                 d. Nummer
  move.l    d0,d2             ; Nummer in d2.l merken
  bpl       Get_Programm      ; Alles Ok -> Get_Programm
  MDosErr   "Keine Versionsnummer oder Fehler in Nummer"

Get_Programm:
  movea.l   a2,a0             ; a0.l wiederholen
  adda.l    d1,a0             ; Versionsnummer überspringen
  bsr       Skip_Space        ; Spaces überspringen
  move.l    a0,d1             ; d1.l -> ^Programmname

  movea.l   SysBase,a6        ; a6.l -> SysBase
  cmp.w     LIB_VERSION(a6),d2; Library Version prüfen
  bne       End               ; Version stimmt nicht -> End
  bsr       Start_Programm    ; Programm starten
  cmpi.l    #-1,d0            ; Ok ?
  beq       End_Error         ; Nein -> End_Error
  bra       End

Help:
  lea       HelpTxt,a0        ; a0.l -> ^HelpTxt
  bsr       Print_0           ; Text ausgeben

End:
  MCloseLib DosBase           ; Dos-Lib schließen
  MPull     d2/a2/a6
  moveq.l   #RETURN_OK,d0
  rts
;------------------------------

End_Error:
  MCloseLib DosBase           ; Dos-Lib schließen
  MPull     d2/a2/a6
  move.l    #RETURN_FAIL,d0   ; dwn, das war nichts
  rts
;------------------------------

HelpTxt: dc.b "VERSION/A, PROGRAMM/A",10,0
  EVEN
;---------------------------------------------------------------

Start_Programm:
; Fkt: Übergebenes Programm starten.
; Ein: - d1.l -> ^Name des Programms (Ende mit Nullbyte)
; Aus: - d0.l ->   -1: Programm konnte nicht gestartet werden
;                <>-1: Alles Ok
; Bme: - Unter Kickstart 1.2/1.3 wird nur zurückgegeben, ob "RUN" aus den
;        C: Directory gestartet werden konnte!!!
;      - Es wird nicht überprüft, ob das gestartete Programm fehlerfrei
;        lief.

  MPush     d2/d3/a6          ; Register retten

  movea.l   SysBase,a6         ; a6.l -> SysBase
  cmp.w     #37,LIB_VERSION(a6); >= OS 2.4 ?
  bcc       OS2.04             ; Ja -> OS2.04

; *** Start unter Kickstart 1.2/1.3 ***
  moveq.l   #0,d2             ; d2.l -> 0 (Input)
  moveq.l   #0,d3             ; d3.l -> 0 (Output)
  CallDos   _LVOExecute       ; Befehl starten
  addq.l    #1,d0             ; d0.l um eins erhöhen
  beq       Start_Programm_End; Alles Ok -> Start_Programm_End
  moveq.l   #-1,d0            ; , sonst d0.l -> -1
  bra       Start_Programm_End

OS2.04:
  move.l    #Dos_Tags,d2      ; d2.l -> Dos-Tags, da sie nur aus TAG_DONE
  CallDos   _LVOSystem        ; bestehen, könnte man hier wohl auch null
                              ; angeben, allerdings hab ich das RKM:
                              ; Libraries noch nicht, so daß ich hier mal
                              ; lieber so vorgehe.

Start_Programm_End:
  MPull     d2/d3/a6          ; Register zurückholen
  rts
;------------------------------

Dos_Tags: dc.l TAG_DONE,0
;---------------------------------------------------------------

Get_Dec:
; Fkt: String in Dezimalzahl(5-stellig) umwandeln (nur positive Zahlen
;      möglich !)
; Ein: - a0.l: ^String
; Aus: - d0.l  = -1: Fehler aufgetreten
;             <> -1: Nummer
;      - d1.l      : Länge des Strings

  MPush     d2/d3             ; Register retten


  MPush     a0
  bsr       Length            ; d0.l -> Länge (Ende mit Space, LF, 0)
  MPull     a0

  move.l    d0,d3             ; d3.l -> Länge
  beq       Get_Dec_Error     ; Länge = 0 -> Get_Dec_Error
  cmpi.l    #5,d0             ; Länge > 5 ?
  bhi       Get_Dec_Error     ; Ja -> Get_Dec_Error

  subq.l    #1,d0             ; d0.l für dbra berichtigen
  moveq.l   #0,d1             ; d1.l -> 0

Get_Dec_Loop:
  move.b    (a0)+,d2          ; d2.b -> Ziffer
  cmpi.b    #"0",d2           ; Ziffer < "0" ?
  bcs       Get_Dec_Error     ; Ja -> Get_Dec_Error
  cmpi.b    #"9",d2           ; Ziffer > "9" ?
  bhi       Get_Dec_Error     ; Ja -> Get_Dec_Error

  subi.b    #"0",d2           ; ASCII in Zahl umwandeln
  mulu      #10,d1            ; Endergebnis um eine Zehnerstelle
                              ; verschieben
  add.b     d2,d1             ; Neue Zahl anhängen

  dbra      d0,Get_Dec_Loop   ; Schleife tun

  move.l    d1,d0             ; d0.l -> Endergebnis
  move.l    d3,d1             ; d1.l -> Länge des Strings

  MPull     d2/d3             ; Register wiederherstellen
  rts
;------------------------------

Get_Dec_Error:
  moveq.l   #-1,d0            ; d0.l -> -1 (Fehler)
  MPull     d2/d3             ; Register wiederherstellen
  rts
;---------------------------------------------------------------

Length:
; Fkt: Länge eines Strings ermitteln (Ende mit Space, LF, 0)
; Ein: - a0.l: ^String (Ende mit Space, LF, 0)
; Aus: - d0.l: Länge des Strings

   MPush    a0                ; a0 auf Stack
   bsr      Find_End          ; a0.l -> ^Stringende
   MPull    a1                ; a1.l -> ^Stringanfang
   suba.l   a1,a0             ; a0.l -> ^StringEnde - ^Stringanfang
   move.l   a0,d0             ; d0.l -> Länge
   rts
;---------------------------------------------------------------

Length_0:
; Fkt: Länge eines Strings ermitteln (Ende mit Nullbyte)
; Ein: - a0.l: ^String (Ende mit Nullbyte)
; Aus: - d0.l: Länge des Strings

   moveq.l  #0,d0             ; d0.l löschen

Length_0_Loop:
   addq.l   #1,d0             ; d0.l -> d0 + 1
   tst.b    (a0)+             ; Null ?
   bne      Length_0_Loop     ; Nein -> Weiter suchen

   subq.l  #1,d0              ; d0.l berichtigen
   rts
;---------------------------------------------------------------

Skip_Space:
; Fkt: Space-Zeichen überspringen.
; Ein: - a0.l: ^String (Ende mit 0 oder LF)
; Aus: - a0.l: ^1.Zeichen nach Space-Zeichen

   move.b   (a0)+,d0          ; d0.b -> Zeichen
   beq      Skip_Space_End    ; Null     -> Skip_Space_End
   cmpi.b   #10,d0
   beq      Skip_Space_End    ; Linefeed -> Skip_Space_End
   cmpi.b   #" ",d0           ; Space ?
   beq      Skip_Space        ; Ja -> Skip_Space

Skip_Space_End:
   subq.l   #1,a0             ; a0.l berichtigen
   rts
;----------------------------------------------------------

Find_End:
; Fkt: Ende eines Strings suchen (Ende mit Space, LF, 0)
; Ein: - a0.l: ^String (Ende mit Space, LF, 0)
; Aus: - a0.l: ^Ende des Strings, also auf das Space, LF bzw. 0
;              Zeichen.

  move.b    (a0)+,d0          ; d0.b -> Zeichen
  beq       Find_End_End      ; Null     -> Find_End_End
  cmpi.b    #10,d0
  beq       Find_End_End      ; Linefeed -> Find_End_End
  cmpi.b    #" ",d0           ; Space ?
  bne       Find_End          ; Nein -> Find_End

Find_End_End:
  subq.l  #1,a0               ; a0.l berichtigen
  rts
;----------------------------------------------------------

Print_0:
; Fkt: Mit null endenden String in aktuelle Ausgabe ausgeben.
; Ein: - a0.l: ^String (Ende mit Nullbyte)

  MPush     d2/d3/a6

  move.l    a0,d2             ; d2.l -> a0 (^String)
  bsr       Length_0          ; d0.l -> Stringlänge
  move.l    d0,d3             ; d3.l -> Stringlänge
  CallDos   _LVOOutput        ; Output Handle holen
  move.l    d0,d1
  CallDos   _LVOWrite

  MPull     d2/d3/a6
  rts
;---------------------------------------------------------------

DosBase: dc.l 0               ; Platz für Basisadr., muß mit null
                              ; initialisiert werden (siehe MCloseLib).
Version: dc.b "$VER: Select 1.0 (11.08.92)",0 ; Versions-String
  EVEN
;---------------------------------------------------------------

   END


                          Tschüß !!!
