ERROR!#

Author : Erhard Pütz
Language: ACTION!

Im unten gezeigten Quellcode steht folgende Zeile:

INCLUDE "D:ERROR.LIB"

ERROR.LIB ist aus der orginal Runtime gekürzt. Da ist immer noch deutlich mehr drin, als das Programm unten braucht, aber es war das, was auf die Schnelle machbar war.

Wenn also aus dem unten gezeigten Quellcode ein fertiges COM-File werden soll:

- bitte eine Runtime oder Mini-LIBs (davon gibt es noch nicht alle) einbinden
- das kompilierte Programm abspeichern
- das Kompilat in z.B. BeWe-Softs Superpacker laden
- aus der INIT-Adresse eine RUN-Adresse machen
- CLR_80FF voranstellen mit INIT-Adresse voranstellen
- das Ganze als ERROR07.COM (oder ERROR.COM) abspeichern

CLR_80FF ist eine kleine Maschinenroutine, die die Speicheradressen $80-$FF nullt. Ich habe festgestellt, daß die nach dem Laden eines DOS sehr oft nicht Null sind, weil sie als beliebte freie ZP-Adressen von so allerlei Zeugs benutzt werden.

Allerdings werden sie auch von ACTION! und ACTION!-Programmen benutzt und wenn man nicht peinlich darauf achtet, daß man in seinem ACTION!-Programm alle Variablen sauber initialisiert, dann wird aus z.B.

WHILE a=0

schon mal eine Schleife, die überhaupt nicht ausgeführt wird.

Also hier noch mal ein Hinweis zur sauberen Variableninitialisierung:

Beispiel 1 (so ist es schlecht, weil die Variable nur beim Kompilieren gesetzt wird):

MODULE
BYTE I=[0]
...

Beispiel 2 (so ist es viel besser, weil die Speicherstelle bei jedem Programmstart gesetzt wird):

MODULE
BYTE I
...
PROC MAIN()
  I=0
...
RETURN

ERROR07.ACT
Und hier nun das, worum es eigentlich geht:

;**************************************
;*                                    *
;* Dieses Programm soll numerische    *
;* Fehlermeldungen von DOS in den     *
;* entsprechenden Text umwandeln.     *
;*                                    *
;* Betriebssystem: Sparta DOS 3.x     *
;*                 BeWeDOS            *
;*                                    *
;* Author   : Erhard Puetz            *
;* Web      : www.atari-central.de    *
;* Datum    : 2012-06-08              *
;* Version  : 0.7 vom 2012-08-11      *
;*                                    *
;* Dateiname: ERRORxx.COM             *
;*            xx = Version            *
;*                                    *
;**************************************


MODULE

SET   14 = $4000 ;compiled program start address
SET $491 = $4000

BYTE RTS=[$60] ;dummy RTS as first byte


;-- Angepasste Runtime mit nur den Routinen,
;-- die das Hauptprogramm verwendet plus den
;-- Routinen, von denen andere abhängig sind.

INCLUDE "D:ERROR.LIB"

;--

MODULE

CHAR ARRAY VERSION = "Version 0.7"
CARD ARRAY MSG(43)

PROC SETERR()
  MSG(00)="128 ($80) BREAK abort"
  MSG(01)="129 ($81) IOCB already open"
  MSG(02)="130 ($82) Non-existent device"
  MSG(03)="131 ($83) Not open for read"
  MSG(04)="132 ($84) Invalid IOCB command"
  MSG(05)="133 ($85) Channel not open"
  MSG(06)="134 ($86) Bad IOCB number"
  MSG(07)="135 ($87) Not open for write"
  MSG(08)="136 ($88) End of file"
  MSG(09)="137 ($89) Truncated record"
  MSG(10)="138 ($8A) Device timeout"
  MSG(11)="139 ($8B) Device NAK"
  MSG(12)="140 ($8C) (n/a)"
  MSG(13)="141 ($8D) (n/a)"
  MSG(14)="142 ($8E) (n/a)"
  MSG(15)="143 ($8F) (n/a)"
  MSG(16)="144 ($90) Device Done Error (Bad Sector, Disk write protected"
  MSG(17)="145 ($91) (n/a)"
  MSG(18)="146 ($92) Function not implemented in handler"
  MSG(19)="147 ($93) (n/a)"
  MSG(20)="148 ($94) Not a SpartaDOS disk"
  MSG(21)="149 ($95) Disk not SpartaDOS 2.x"
  MSG(22)="150 ($96) Directory not found"
  MSG(23)="151 ($97) File (or directory) with same name exists"
  MSG(24)="152 ($98) Not a binary file"
  MSG(25)="153 ($99) (n/a)"
  MSG(26)="154 ($9A) (n/a)"
  MSG(27)="155 ($9B) (n/a)"
  MSG(28)="156 ($9C) (n/a)"
  MSG(29)="157 ($9D) (n/a)"
  MSG(30)="158 ($9E) (n/a)"
  MSG(31)="159 ($9F) (n/a)"
  MSG(32)="160 ($A0) Drive number error"
  MSG(33)="161 ($A1) (n/a)"
  MSG(34)="162 ($A2) Disk full"
  MSG(35)="163 ($A3) Illegal wild card in filename"
  MSG(36)="164 ($A4) File erase protected"
  MSG(37)="165 ($A5) File name error (illegal characters in filename)"
  MSG(38)="166 ($A6) Position range error"
  MSG(39)="167 ($A7) Cannot delete directory"
  MSG(40)="168 ($A8) Illegal DOS command / not implemented"
  MSG(41)="169 ($A9) Disk is write locked"
  MSG(42)="170 ($AA) File not found"
RETURN


PROC FEHLER(BYTE I)

  BYTE ARRAY ERRMSG

  SETERR()
  IF I>127 AND I<171 THEN
    ERRMSG=MSG(I-128)
    PRINTE(ERRMSG)
  ELSE
    PRINTB(I)
    PRINT(": ")
    PRINTE("Nur Fehler von 128 bis 170")
  FI
  PUT(155)
RETURN


BYTE FUNC CHK_DOS()

  ;RETURNS DOS OK 0=NO 1=YES

  BYTE DFLAG=$700
  BYTE DVER=$701

  IF DFLAG='S AND DVER=$32 OR
     DFLAG='S AND DVER=$33 OR
     DFLAG='R AND DVER=$10 THEN
     RETURN(1)
  FI

  PRINTE("Not SpartaDOS 3.X, BW-DOS")
  PRINTE("or RealDOS 1.0")
RETURN(0)


PROC ZCRNAME()
;
;Diese Routine enthaelt keinen ACTION-Code.
;Die Adresse von ZCRNAME wird durch CRUNCH
;auf SpartaDOS's COMTAB+3 geaendert. Beim
;Aufruf von ZCRNAME wird dann der dortige
;Maschinencode ausgefuehrt.
;
RETURN ;Dummy RETURN, ML ends with RTS   


CARD FUNC CRUNCH()
;
;Diese Routine dient zum Auslesen der Parameter,
;die in der Kommandozeile des DOS übergeben wurden.
;
  BYTE I
  CARD COMTAB=$0A,
       COMFNAM,
       PAR
  BYTE POINTER BUFOFF,
               LBUF

  ZCRNAME=COMTAB+3
  BUFOFF =COMTAB+10
  COMFNAM=COMTAB+33+2
  LBUF   =COMTAB+63

  PAR=0

;Errechne Laenge der Eingabezeile -> "I"
  I=0
  WHILE LBUF^#155 DO
    I==+1
    LBUF==+1
  OD

  IF BUFOFF^ < I THEN
    ZCRNAME()
    PAR=VALB(COMFNAM)
    ;GET ALL PARMS AND PRINT THEM
    PRINTE(" ")
    WHILE BUFOFF^ < I DO
      ZCRNAME()
      PRINT("* ueberz. Parameter: ")
      PRINTE(COMFNAM)
    OD
  ELSE
    PRINTE(" ")
    PRINT("(c) 2012 Erhard Puetz, ")
    PRINTE(VERSION)
    PRINTE(" ")
    PRINTE("Syntax:")
    PRINTE(" ")
    PRINTE("ERROR num")
    PRINTE(" ")
    PRINTE("num   Eine Nummer on 128 - 170")
    PRINTE(" ")
    PAR=$8000
  FI
RETURN(PAR)


PROC MAIN()
;
;Programm startet hier.
;Bei gueltiger DOS Version Auslesen der
;Kommandozeile und Uebergabe der Fehlernummer
;zur Ausgabe der Fehlermeldung.
;
  BYTE VALID,
       ERR_NO
  CARD CRUNCH_RESULT

  VALID=CHK_DOS()

  IF VALID=1 THEN
    CRUNCH_RESULT=CRUNCH()
    IF CRUNCH_RESULT < 255 THEN
      ERR_NO=CRUNCH_RESULT
      FEHLER(ERR_NO)
    FI
  FI
RETURN