← ST-Computer 11 / 1989

Somewhere over the Rainbow: Intimes zu TOS 1.4

Grundlagen

Nun ist es endlich soweit - die von vielen lang erwartete neue Version unseres Lieblings-Betriebssystems TOS ist fertig. Das neue TOS 1.4 wurde auf der DĂŒsseldorfer ATARI-Messe offiziell vorgestellt und endgĂŒltig freigegeben. Dies ist Grund genug, es auch unseren Lesern vorzustellen.

TOS 1.4 hört auch auf den Decknamen “Rainbow TOS", da das ATARI-Zeichen in der “Desktop info"-Dialogbox in einer farbigen Animation (nur im Farbmodus) zu sehen ist, die wohl an einen Regenbogen erinnern soll (engl. “rainbow" = Regenbogen). Diese offizielle Version datiert vom 6.4.1989 und ist damit zu unterscheiden von den “Beta-Versionen" des Jahres 1988 und dem “Messe-TOS" vom 22.2.1989, das auf der letzten CeBIT zu sehen war.

Erfreulicherweise gibt es fĂŒr Software-Entwickler auch eine Dokumentation, in der Änderungen, Fehler und besondere Programmierhinweise aufgefĂŒhrt sind. Diese Doku ist zwar nicht ganz vollstĂ€ndig und fehlerfrei, aber bietet wesentlich mehr, als man sonst von ATARI gewohnt ist. Überhaupt ist die UnterstĂŒtzung der Software-Entwickler besser geworden, als sie es frĂŒher einmal war. Trotzdem konnte ich es nicht lassen, mir das TOS (speziell BIOS und GEMDOS) ein wenig unter der Lupe anzusehen, sprich zu disassemblieren und recompilieren.

Heute möchte ich Ihnen die Ergebnisse bezĂŒglich des BIOS mitteilen, und zwar in drei Stufen: fĂŒr Anwender, Programmierer und die TOS-Spezialisten, die ihren Computer bis in die letzten Eingeweide kennen möchten. In den nĂ€chsten Ausgaben der ST Computer beschĂ€ftige ich mich dann intensiv mit den Neuerungen beim GEMDOS, in Anlehnung und als ErgĂ€nzung zur GEMDOS-Serie “Auf der Schwelle zum Licht" (ST 1/88-11/88). Auf die fĂŒr Nicht-Programmierer interessanteren Verbesserungen am Desktop wird in dieser Zeitschrift an anderer Stelle eingegangen.

FĂŒr den Anwender

Kommen wir also zunĂ€chst zu den Änderungen, die fĂŒr den Anwender interessant sind. Bekanntlich gibt es die sogenannten boot-fĂ€higen Disketten, d.h. Disketten, von denen beim Reset automatisch ein kleines Programm geladen wird, das allerlei nĂŒtzliche Dinge tun kann. Dazu zĂ€hlen z.B. der “TOS-Loader" von ATARI, mit dem ein RAM-TOS von Diskette gebootet werden kann, Programme, die einem das Einstellen der Systemuhr erlauben oder Hinweise ĂŒber die Diskette ausgeben (Aladin). Es gibt vor allem bei Spielen sogar Boot-Sektor-Programme, die gleich das eigentliche Programm starten (Auto-Start-Disketten). Am verbreitetsten unter den Boot-Programmen sind aber wohl die “Boot-Sektor-Viren", ĂŒber die wohl schon genug geschrieben wurde.

Das Laden und Starten dieser Boot-Programme geschah aber bisher nur beim Kaltstart (d.h. nach dem Einschalten des Rechners) oder wenn keine weiteren boot-fÀhigen Laufwerke vorhanden waren (Harddisk, EPROM-Disk, reset-residente RAM-Disk). Dies ist nun anders, da jetzt bei jedem Reset auf jeden Fall versucht wird, ein Boot-Sektor-Programm von Laufwerk A: zu laden. Dies vereinfacht die Benutzung der oben erwÀhnten Auto-Start-Disketten, erhöht aber auch die Virengefahr. Ferner sollte man nun immer eine Diskette in A: haben, wenn man nicht von Diskette bootet, da der Boot-Vorgang sonst unnötig lange dauert (wegen des versuchten Zugriffs auf eine nicht vorhandene Diskette).

Beim Booten von Harddisk (oder anderen DMA-GerĂ€ten) wird nun beim Lesen des Boot-Sektors ein zweiter Versuch gemacht, falls beim ersten ein Fehler auftrat. Ausgenommen ist der Fall, daß keine Harddisk angeschlossen ist; dann wird weiterhin nur ein Leseversuch gemacht.

Eine wichtige und schwierige Aufgabe des TOS ist die sichere Erkennung von Diskettenwechseln, da sonst sehr leicht Daten auf Disketten zerstört werden können. Bei Benutzung eines physikalischen Laufwerks als zwei logische Laufwerke, was zur bekannten hĂ€ufigen Aufforderung “Bitte Disk X: in Floppy A: einlegen" fĂŒhrt, konnte es passieren, daß ein Diskettenwechsel nicht erkannt wurde, wenn er und die BestĂ€tigung dieser Aufforderung sehr schnell (unter 1,5 Sekunden) erfolgten. Dieser Mangel ist nun behoben.

Auch an der Tastaturbehandlung wurde einiges geĂ€ndert. So kann ein Reset nun endlich durch Tastendruck, nĂ€mlich durch CONTROL-ALTERNATE-DELETE, ausgelöst werden. Dabei wird ein Warmstart durchgefĂŒhrt, d.h. reset-residente RAM-Disks usw. bleiben erhalten. Auch ein Kaltstart ist möglich, wenn zusĂ€tzlich noch die rechte SHIFT-Taste gedrĂŒckt wird. Dabei wird fast der gesamte Speicher gelöscht, so daß dies vorher gut ĂŒberlegt sein will.

Die Tastenwiederholung wurde leicht modifiziert. Wenn man eine Taste gedrĂŒckt hielt (z.B. ’a’), bis die Tastenwiederholung ansprach, und dann eine weitere betĂ€tigte (z.B. ’s’), erschien nur ein 's', und die Tastenwiederholung blockierte, bis mindestens eine der Tasten losgelassen und eine weitere gedrĂŒckt wurde. Nun wird auch das ‘s’ automatisch wiederholt, bis eine weitere Taste gedrĂŒckt wird, usw.

FĂŒr den Programmierer

Auch fĂŒr den Programmierer gibt es einige Neuigkeiten. Da wĂ€ren zunĂ€chst einmal eine geĂ€nderte und eine neue XBIOS-Funktion. Die neue XBIOS-Funktion Floprate (Nummer 41) erlaubt das Ermitteln und Verstellen der Floppy-Seek-Rate (Spurwechselzeit), und zwar fĂŒr jedes Laufwerk einzeln. Dies ging bisher nur mit bestenfalls halblegalen Methoden (s. [1], Kapitel 8.2.). Warum ATARI die XBIOS-Nummer 40 unbenutzt gelassen hat, bleibt wohl ein Geheimnis. Die Deklaration in C sieht so aus:

long Floprate(int drive, int rate)

FĂŒr die Nicht-C-Programmierer: Die Funktion hat zwei 16-Bit-Integer-Parameter und liefert einen 32-Bit-Integer-Wert zurĂŒck. Der erste Parameter drive gibt das Laufwerk an (0 oder 1, andere Werte sind zu vermeiden), der zweite die neue Seek-Rate. rate ist dabei genauso wie die Systemvariable i ($440) kodiert. Werte von 0 bis 3 stehen dabei fĂŒr Seek-Raten von 6, 12, 2 bzw. 3 Millisekunden.

Die XBIOS-Funktion Rsconf wurde erweitert und besser dokumentiert. Übergibt man als ersten Parameter (Baud-Rate) den Wert -2, liefert die Funktion die mit Rsconf eingestellte Baud-Rate zurĂŒck. Wenn der MFP-Chip durch direkten Zugriff programmiert wird, bemerkt dies

# Übersicht ĂŒber das BIOS des TOS 1.4 ; L=siehe Listing, T=siehe Text ; sonst inhaltlich unverĂ€ndert fc0000 L system header block fc0030 reset, Kaltstart fc01f2 L Warmstart fc0530 von Floppy booten fc054c von DMA booten fc0578 L Boot-Sektor von DMA-Bus laden fc060e DMA-Kommandobyte ausgeben fc0628 ROM-Modul testen und init. fc0652 Dummy-RTS-Routine fc0654 RAM-Lesetest fc066a Speicherkonfigurationstest fc068a Standard-BIOS-Farbpalette fc06aa HBL-Handler fc06c0 L VBL-Handler fc07a2 XBIOS-Vsync fc07ba BIOS-Critical-Error-Handler fc07c4 TRAP #14/TRAP #13-Handler fc0950 XBIOS-Supexec fc0956 BIOS-Bcon... fc09f8 BIOS-Drvmap fc09fe BIOS-Kbshift fc0a10 BIOS-Getmpb fc0a3c BIOS-Setexc fc0a54 BIOS-Tickcal fc0a5c XBIOS-Physbase/Logbase/Getrez/Setscreen fc0ac4 XBIOS-Setpalette/Setcolor fc0af0 XBIOS-Puntaes fc0b0a Bömbchen-Routinen fc0bb6 Sektor kopieren fc0bd8 Laufwerke init. (Sprung ĂŒber hdv_init) fc0bf4 Auto-Ordner-Programme ausfĂŒhren fc0efa XBIOS-Scrdmp fc0d0c ĂŒber 'dumpvec' aufgerufene Hardcopy-Routine fc0dc2 Timer-B-ZĂ€hlroutine fc0dfe reset-residente "PĂ€ckchen"-Programme suchen und ausfĂŒhren fc0e3e XBIOS-Gettime/Settime fc0e62 Kopie des System-header-blocks anlegen fc0e9e XBIOS-Blitmode fc0ec6 Test, ob Blitter vorhanden Floppy-Routinen fc0ef0 Laufwerk init. (flopini) fc0f38 XBIOS-Floprd fc0fe8 Fehlernummer aus FDC-Fehler bestimmen fc100a XBIOS-Flopwr fc10c6 XBIOS-Flopfmt fc1286 XBIOS-Flopver fc1360 Floppy-VBL-Handler fc13dc floplock fc145c flopfail fc146a flopok fc14b0 Spur ansteuern fc14ce Restore und Seek fc1502 Spur suchen (go2track) fc1528 Restore fc153e FDC-Kommando schicken fc1582 FDC-Reset fc159c Laufwerk und Seite selektieren (2 Routinen) fc16d8 Kommando-Bytes an FDC schicken fc1640 L Test auf Diskettenwechsel fĂŒr 'Bitte Disk einlegen...' fc1682 DSB neu setzen fc1692 L *** XBIOS-Floprate: Seek-Rate ermitteln/neu setzen *** fc16ba T Floppy-hdv_init fc1732 BIOS-Getdsb fc173c BIOS-Getbpb fc18ec T BIOS-Mediach fc1956 interne Diskettenwechsel-Routine fc1a24 BIOS-Rwabs fc1aac floprw fc1c76 XBIOS-Random fc1cc6 L Floppy-hdv_boot fc1d42 T XBIOS-Protobt fc1e2e Checksumme fĂŒr Boot-Sektor berechnen fc1e5e Intel- nach Motorola-Format wandeln

Rsconf nicht und liefert einen falschen Wert. Die restlichen Parameter sind bei diesem Aufruf beliebig.

Rsconf hat laut ATARI-XBIOS-Dokumentation keinen RĂŒckgabewert, aber schon immer wurden die MFP-Register UCR, TSR, RSR und UDR vor dem Rsconf zurĂŒckgeliefert (außer bei einer “Baud-Rate” von “-2”). Dabei sind alle vier Register in einem Langwort zusammengepackt (UCR im höchstwertigen Byte, usw.). Die Rainbow-TOS-Dokumentation segnet diese nun ab, doch spricht sie dabei von den Registern SCR, UCR, RSR und TSR. Diese Bezeichnungen wĂ€ren auch sinnvoller, da dies die Register sind, die man mit Rsconf auch setzen kann.

Protobt soll “IBM-kompatiblere” Boot-Sektoren erzeugen. Die einzige Änderung, die ich feststellen konnte, ist ein verĂ€ndertes Media-Byte im Boot-Sektor bei einseitigen 80-Track-Disketten. Statt $F8 steht hier nunmehr $F9, obwohl eigentlich unter PC-DOS $F8 vorgesehen ist ([1]). Da ich zu wenig von PC-DOS verstehe, kann ich nicht sagen, ob das ein neuer Fehler oder tatsĂ€chlich eine Verbesserung ist. Um volle MS-DOS-KompatibilitĂ€t zu erreichen, sollen die ersten drei Bytes im Boot-Sektor $E9,$00,$4E sein. Der eigentliche Fortschritt besteht aber in einer verbesserten Formatierroutine des Desktops, die das Media-Byte in der FAT und die ersten drei Bytes im Boot-Sektor richtig setzt.

Die “Bömbchen”-Routine, die unerwartete Exceptions “behandelt”, terminiert das aktive Programm nun mit Pterm(-1) statt mit Pterm(0), so daß das ĂŒbergeordnete Programm 0x0000ffff von Pexec zurĂŒckbekommt.

Eigene Tastatur-Interrupt-Routinen standen immer vor dem Problem, “normale” TastendrĂŒcke von aus mehreren Bytes bestehenden “Paketen” (z.B. Maus-Bewegungs-Paket) unterscheiden zu mĂŒssen. Am Offset $24 ab dem von Kbdvbase zurĂŒckgelieferten Zeiger fand sich in allen TOS-Versionen ein Byte-Flag, das anzeigt, ob gerade ein aus mehreren Zeichen bestehendes “Paket” vom Tastaturprozessor erwartet wird. Ab nun ist seine Lage (dieser Offset) offiziell dokumentiert.

Eigene Tastatur-Interrupt-Routinen. die sich in den ikbdsys-Vektor einklinken und TastendrĂŒcke einer “Sonderbehandlung” unterziehen wollen, sollten Bytes nur berĂŒcksichtigen, wenn das Flag Null ist.

Diverses fc1e84 Hardcopy-Ausgaberoutinen (4 StĂŒck) fc1ee0 superschnelle Löschroutine fc1f4c MEGA-Uhr nach GEMDOS-Ühr fc1f70 L Test, ob MEGA-Uhr vorhanden fc1fc2 Gettime fĂŒr MEGA-Uhr fc2080 Settime fĂŒr MEGA-Uhr fc215c Hardcopy IKBD, RS232, Centronics, MFP fc315e Uhrzeit-Paket in BIOS-Format umrechnen fc31a8 L IKBD-Gettime fc31d2 IKBD-Settime fc3240 Byte -> BCD fc3254 BCD -> Byte fc326a MIDI-I/O-Routinen fc32f6 L Centronics-I/O-Routinen fc33a6 RS232-Routinen (Ein-/Ausgabe und Status) fc344a IKBD-Routinen (Ausgabe und Status) fc3480 XBIOS-Ikbdws fc3494 Tastatur-Routinen (Eingabe, Status, Ausgabestatus) fc34e4 "Glocke" starten fc34fc MFP init. fc365e Default-IOREC-Daten und RS232-Interrupt-Vektoren fc36ac MFP-Timer init. fc3754 XBIOS-Mfpint fc377e XBIOS-Jdisint/Jenabint fc37f2 RS232-Interrupt-Routinen (4 StĂŒck) fc3932 weitere RS232-Routinen fc39fe XBIOS-Iorec fc3a16 L XBIOS-Rsconf fc3aec T IKBD/MIDI-Interrupt fc3c70 L Keyboard-Interrupt fc3fbe MIDI-Eingabe-Interrupt fc3fec Maus-Emulator fc4034 L *** Shift-Ctrl-Alt-Routine *** fc407e XBIOS-Giaccess/Ongibit/Offgibit fc4102 XBIOS-Initmous fc41cc XBIOS-Xbtimer fc4206 XBIOS-Keytbl/Bioskeys fc424c XBIOS-Dosound fc4260 XBIOS-Setprt fc4272 XBIOS-Kbrate/Kbdvbase fc429c 200 Hz-Interrupt-Handler fc42fe Sound-Interrupt-Routine (ohne Sound-Daten) Ende des BIOS fc4388 GEMDOS und BIOS-Routinen fĂŒr GEMDOS BIOS-Bildschirmtreiber fca2ec VDI-ESC-Handler fca342 VDI-ESC 101 fca358 ASCII-Out/Conout-Einsprung fca38e CTRL-Kodes fca3b4 TAB fca3c6 T ESC-Behandlung fca45c ESC-Verteiler fca4b6 VDI ESC 1 fca4d8 VDI ESC 17,3,2, ESC E,A,C,D,H fca540 Rest-Bildschirm, -Zeile löschen fca564 VDI ESC 11,13,14,15,16,18,19 fca5e8 ESC I,L,M fca636 Cursor ein, ESC e,f,j,k,l fca6b6 Bildschirmbereich löschen, LF fca720 XBIOS-Cursconf fca778 ASCII-Zeichen ausgeben fca846 T Blitter-Routine #0 fca8d4 ab Cursor nach oben scrollen fca8da T Blitter-Routine #1 fca936 ab Cursor nach unten scrollen fca93c T Blitter-Routine #2 fca9b4 Bildschirmbereich löschen fcaa46 Cursor positionieren fcab20 ... fcb4fc TOS-Bildschirmausgabe je nach Auflösung init. fcb586 Blitter-Vektoren installieren fcb5a0 ... fcb5de Blitter-Vektor-Tabelle laden fcb65e ...

Es wird vom BIOS auf ungleich Null gesetzt, wenn ein Header-Byte eines “Paketes” empfangen wurde, und ist wieder Null, wenn der Empfang des “Pakets” beendet ist. Wenn man das Flag abfragen möchte, bevor man seine Interrupt-Routine installiert, sollte man zuerst solange warten, bis es Null wird, dann das Interrupt-Level (IPL) der CPU auf 7 setzen. und, falls das Flag nun schon wieder gesetzt ist, den IPL wieder zurĂŒcksetzen und erneut warten. Ansonsten kann ikbsys neu gesetzt und der IPL restauriert werden. So schlĂ€gt es ATARI vor. Ich wĂŒrde zusĂ€tzlich noch eine Timeout-Abfrage einbauen, um eine Endlosschleife zu verhindern, falls das “Paket” aus irgendwelchen GrĂŒnden nicht vollstĂ€ndig gesendet wird bzw. ankommt.

Hier noch einige ErklĂ€rungen zur verbesserten Diskettenwechselerkennung, die oben schon erwĂ€hnt wurde. Bei jedem Diskettenzugriff merkt sich das BIOS die aktuelle Systemzeit. Die Mediach-Routine meldet nun, wenn es eigentlich einen “unsicheren” Wechselstatus festgestellt hat, trotzdem ein “kein Wechsel”, wenn seit dem letzten Zugriff nicht mehr als eine bestimmte maximale Zugriffszeit vergangen ist. Es geht also davon aus, daß “schnelle” Diskettenwechsel (kĂŒrzer als die maximale Zugriffszeit) nicht möglich sind. Dies spart das zu hĂ€ufige Lesen des Boot-Sektors bei schreibgeschĂŒtzten Disketten (wo ein unsicherer Status stĂ€ndig auftritt).

Bisher wurde zur Zeitmessung der 200-Hz-ZĂ€hler (_hz_200) benutzt, nun wird frclock genommen (warum nur?). Daher ist die maximale Zugriffszeit jetzt von der Bildwiederholfrequenz abhĂ€ngig. Sie liegt bei 1.2 s, 1,37 s bzw. 1,64 s fĂŒr 71 Hz, 60 Hz bzw. 50 Hz Bildwiederholfrequenz (bisher immer 1,5 s). Daher wird in hdvjnit die interne Variable fĂŒr die maximale Zugriffszeit auf 82 statt bisher 300 gesetzt. Die eigentliche Verbesserung besteht nun darin, daß die gemerkte letzte Zugriffszeit beim Wechsel zwischen den logischen Laufwerken A: und B: nach der Aufforderung “Bitte Disk X: in Floppy A: einlegen” auf Null gesetzt wird. Damit liefert Mediach nach einem solchen Wechsel nun auf jeden Fall den wahren Diskettenwechselstatus zurĂŒck; bisher wurde also bei einer Wechselzeit unter 1,5 s der Wechsel von Mediach nicht gemeldet.

BIOS-Listing wesentlich geÀnderter Routinen

;OS Header FCOOOO BRA $FC0030 FC0002 dc.b 1,4 ;Version 1.4 FC0004 dc.l $FC0030 ;Reset-Adresse FC0008 dc.l $FC0000 ;Beginn TOS FC000C dc.l $00611c ;Beginn freies RAM FC0010 dc.l $FC0030 FC0014 dc.l $FE8230 ;Adresse GEM-MAGIC FC0018 dc.l $04061989 ;Default-Systemdatum 22.2.1989 FC001C dc.w 3 ;Land: FRG, PAL-Norm FC001E dc.w $1286 ;Default-Systemdatum im GEMDOS-Format FC0020 dc.l $00378c ;Adresse GEMDOS-Variable 'mifl' FC0024 dc.l $000E7d ;Adresse BIOS-Tastaturvariablen FC0028 dc.l $005622 ;Adresse GEMDOS-Variable 'act_pd' FC002C dc.l 0

Listings wesentlich geÀnderter Routinen

;Warmstart ... FC0432 JSR $FC95C8 ;GEMDOS init. FC0438 MOVE.W $FC001E,$0060BE ;Default-Datum setzen FC0442 JSR $FC1F4C ;MEGA-Uhr ĂŒbernehmen, falls vorhanden FC0448 BCC $FC0462 ;*** -> MEGA-Uhr da *** FC044A BSR $FC31A8 ;*** IKBD-Uhr auslesen *** FC044E SWAP D0 ;*** Datum holen *** FC0450 TST.B D0 ;*** *** FC0452 BEQ $FC0462 ;*** -> "Zeit ungĂŒltig" *** FC0454 MOVE.W D0,$0060BE ;*** Datum ĂŒbernehmen *** FC045A SWAP D0 ;*** *** FC045C MOVE.W D0,$00378A ;*** Zeit ĂŒbernehmen *** FC0462 BSR $FC0530 ;Floppy-Boot versuchen ;Boot-Sektor vom DMA-Bus laden ;A4 von DMA-Boot-Routine gelöscht FC0578 MOVEQ #$01,D5 ;*** 2 Versuche *** FC057A LEA $8606(A4),A6 ;alles wie bisher... FC057E LEA $8604(A4),A5 FC0582 ST $043E(A4) FC0586 MOVE.L $04C6(A4),-(A7) FCO58A MOVE.B $0003(A7),$860D(A4) FC0590 MOVE.B $0002(A7),$860B(A4) FC0596 MOVE.B $0001(A7),$8609(A4) FC059C ADDQ.W #4,A7 FC059E MOVE.W #$0098,(A6) FC05A2 MOVE.W #$0198,(A6) FC05A6 MOVE.W #$0098,(A6) FC05AA MOVE.W #$0001,(A5) FC05AE MOVE.W #$0088,(A6) FC05B2 MOVE.B D7,D0 FC05B4 OR.B #$08,D0 FC05B8 SWAP D0 FC05BA MOVE.W #$008A,D0 FC05BE BSR $FC060E FC05C0 BNE $FC05F0 ;-> Timeout bei Kommando-Byte: Abbruch FC05C2 MOVEQ #$03,D6 FC05C4 LEA $FC05FE(PC),A0 FC05C8 MOVE.L (A0)+,D0 FC05CA BSR $FC060E FC05CC BNE $FC05F0 ;-> Timeout bei Kommando-Byte: Abbruch FC05CE DBF D6,$FC05C8 FC05D2 MOVE.L #$0000000A,(A5) FC05D8 MOVE.W #$0190,D1 FC05DC BSR $FC0612 FC05DE BNE $FC05F0 ;-> Timeout bei Kommando-Byte: Abbruch FC05E0 MOVE.W #$008A,(A6) FC05E4 MOVE.W (A5),D0 ;DMA-Statusregister FC05E6 AND.W #$00FF,D0 FC05EA BEQ $FC05F2 ;-> ok FC05EC DBF D5,$FC057A ;*** DMA-Fehler: neuer Versuch *** FC05F0 MOVEQ #$FF,D0 ;Fehlermeldung FC05F2 MOVE.W #$0080,(A6) ;Rest wie bisher... FC05F6 TST.B D0 FC05F8 SF $043E(A4) FC05FC RTS ;VBL-Routine FC06C0 ADDQ.L #1,$000466 ;zunĂ€chst wie bisher FC06C6 SUBQ.W #1,$000452 FC06CC BMI $FC079A FC06D0 MOVEM.L D0-A6,-(A7) FC06D4 ADDQ.L #1,$000462 FCO6DA SUBA.L A5 , A5 FC06DC MOVE.B $FA01(A5),D1 ;*** Monochrom-Bit nur einmal lesen *** FC06E0 MOVE.B $8260(A5),D0 FC06E4 AND.B #$03,D0 FC06E8 CMP.B #$02,D0 FC06EC BGE $FC0702 FC06EE BTST #$07,D1 ;*** Abfrage im Register *** FC06F2 BNE $FC0722 FC06F4 MOVE.W #$07D0,D0 FC06F8 DBF D0,$FC06F8 FC06FC MOVE.B #$02,D0 FC0700 BRA $FC0714 FC0702 BTST #$07,D1 ;*** Abfrage im Register *** FC0706 BEQ $FC0722 ... ;ab hier weiter wie bisher ;Diskettenwechsel-Aufforderung FC1640 CMPI.W #$0001,$0004A6 ;zunĂ€chst nichts Neues FC1648 BNE $FC1680 FC164A MOVE.W $0010(A7),D0 FC164E CMP.W $000ED4,D0 FC1654 BEQ $FC167C FC1656 MOVE.W D0,-(A7) FC1658 MOVE.W #$FFEF,-(A7) FC165C BSR $FC07BA FC1660 ADDQ.W #4,A7 FC1662 MOVE.W #$FFFF,$0009FA ;Schreibschutzstatus A,B unsicher FC166A LEA $0009FC,A0 ;*** letzte Zugriffszeit *** FC1670 CLR.L (A0)+ ;*** rĂŒcksetzen fĂŒr A: *** FC1672 CLR.L (A0) ;*** und B *** FC1674 MOVE.W $0010(A7),$000ED4 ;akt. Floppy neu setzen FC167C CLR.W $0010(A7) FC1680 RTS ;XBIOS #41: Seek-Rate ermitteln/neu setzen FC1692 LEA $000A4C,A0 ;DSB Floppy A FC1698 TST.W $0004(A7) ;Laufwerk FC169C BEQ $FC16A4 FC169E LEA $000A50,A0 ;DSB Floppy B FC16A4 MOVE.W $0002(A0),D0 FC16A8 MOVE.W $0006(A7),D1 ;neue Seek-Rate FC16AC CMP.W #$FFFF,D1 FC16B0 BEQ $FC16B6 ;-> nein: nur lesen FC16B2 MOVE.W D1,$0002(A0) ;neue Seek-Rate setzen FC16B6 EXT.L D0 ;akt. Seek-Rate zurĂŒck FC16B8 RTS

Die folgenden Änderungen sind von ATARI nicht dokumentiert worden, aber trotzdem wahr.

Die ESC Y-Funktion des VT52-Emulators zum Setzen der Cursor-Position kontrolliert nun den Spalten- und Zeilenparameter. Bei Werten grĂ¶ĂŸer als die maximale Spalte bzw. Zeile wird der Maximalwert benutzt. Bisher wurden beliebige Koordinaten “geschluckt”. Negative Werte werden weiterhin nicht abgefangen.

Die XBIOS-Funktion Gettime blieb bisher in einer Endlosschleife hĂ€ngen, wenn das vom Tastaturprozessor angeforderte Uhrzeit-Paket nicht ankam. Nun erfolgt nach einer Sekunde ein Timeout, und Gettime liefert dann Null zurĂŒck.

Die ĂŒber die IOREC-Strukturen verwalteten I/O-Puffer fĂŒr Tastatur, RS232 und Midi durften nur maximal 32 kB groß sein. Jetzt sind sogar 64 kB erlaubt.

FĂŒr Leute, die eigene Interrupt-Routinen ĂŒber die Kbdvbase-Vektoren midisys und ikbdsys einhĂ€ngen, hat TOS 1.4 noch eine Überraschung parat. Vom BIOS werden die Register D0-D3, A0-A3 und A5 gerettet, so daß man annehmen konnte, daß man diese Register selbst nicht retten muß (dokumentiert ist die Programmierung solcher Interrupt-Routinen ja nirgends). Wer nun A5 verĂ€ndert hat, guckt ab TOS 1.4 in die Röhre, da A5 nach Beendigung der eigenen Routinen immer Null sein muß. Dies kommt durch die Code-Optimierungen zustande, die ATARI vorgenommen hat.

Neue garantierte Systemvariablen gibt es eigentlich keine. “Eigentlich” heißt, daß die in frĂŒheren TOS-Versionen unbenutzte Systemvariable $59E (Wort) beim Reset zwar gelöscht, aber sonst nirgendwo im TOS angesprochen wird. Noch merkwĂŒrdiger ist, daß bei der Beta-Version an dieser Stelle stattdessen noch die Systemvariable _bootdev ($446) gelöscht wurde, wozu das auch immer gut sein sollte. Falls dies nicht einfach Unsinn ist, könnte es höchstens sein, daß $59E von einem anderen ATARI-Programm noch benötigt wird (Ă€hnlich dem punptr des Harddisk-Treibers), wer weiß.

Der system header block, der am Anfang des TOS zu finden ist (die Systemvariable _sysbase ($4f2) zeigt darauf), ist nun offiziell dokumentiert (s. Abb. 1). Eine genauere ErlÀuterung findet sich in [4].

Neu ist allerdings die Dokumentation zu den Konfigurations-Bits. Bit 0 steht hier fĂŒr NTSC- bzw. PAL-Fernsehnorm, Bits 1 bis 15 beinhalten eine LĂ€nderkennung (s. Abb. 2).

FĂŒr die Benutzung von p_run aus dem OS-Header ist es wichtig, die Adresse unter TOS 1.0 zu kennen. Bei allen TOS-Versionen außer der spanischen (!) lautet sie $602C, bei der spanischen $873C.

Offset Name C-Datentyp Bedeutung
$00 os_entry unsigned int Sprungbefehl auf Reset-Handler
$02 os_version unsigned int TOS-Versionsnummer
$04 reseth char * Zeiger auf Reset-Handler
$08 os_beg OSHEADER* Zeiger auf diesen Header
$0c os_end char * Zeiger auf Ende des von BIOS/GEMDOS/VDI benutzten RAMs
$10 os_rsv1 char * unbenutzt, reserviert
$14 os_magic char * Zeiger auf Parameterblock fĂŒr Speicherbedarf des GEM
$18 os_date long Datum der TOS-Erstellung (Format $JJJJMMDD)
$1C os_conf unsigned int Konfigurations-Bits (s. Text)
$1E os_dosdate unsigned int Datum der TOS-Erstellung (GEMDOS-Format)
:ab hier erst ab TOS 1.2
$20 p_root char ** Zeiger auf ‘mifl’-Listen
$24 pkbshift char ** Zeiger auf Keyboard-Shift-Variable
$28 p_run char ** Zeiger auf Zeiger des aktuellen GEMDOS-Prozeßdescriptors
$2C p_rsv2 char * unbenutzt, reserviert

Abb. 1: Der “OS-header” (OSHEADER)

Alte und neue Fehler

Leider hat ATARI einige Fehler im BIOS immer noch nicht beseitigt. BIOS/XBIOS-Aufrufe aus Interrupt-Routinen heraus sind immer noch gefÀhrlich, da die Interrupts wÀhrend des Rettens der Register in die BIOS save area weiterhin nicht gesperrt werden (s. hierzu [2]).

Der Boot Device-Fehler besteht noch immer. Beim Erstellen der Ur-Environment-Strings wird das Boot-Laufwerk fĂ€lschlich mit ‘move.b $446,d0' statt ‘move.w $446,d0’ ermittelt. Beim Laden der Auto-Ordner-Programme ist an einer Stelle eine Stack-Korrektur immer noch falsch (addq #6 statt add #12), was in ungĂŒnstigen FĂ€llen zum Absturz fĂŒhren kann.

Einige Fehler wurden nun zum Feature deklariert, d.h. man muß mit ihnen leben bzw. sie umgehen, wobei auch hier ATARI hilfreich zur Seite steht:

Die Ausgabe-Status-Routinen (Bcostat) fĂŒr Tastaturprozessor und MIDI-Schnittstelle waren und bleiben vertauscht. Bcostat(4) liefert also nun offiziell den MIDI-und Bcostat(3) den IKBD-Status. Witzigerweise ist dies in der TOS-Doku genau verkehrt herum, also so wie es eigentlich sein sollte, angegeben!

screenpt wird nach dem Setzen der neuen Bildschirmadresse in der VBL-Routine nicht gelöscht. Dies fĂŒhrt zu Komplikationen, wenn parallel mit Setscreen gearbeitet wird (s. [4]). ATARI empfiehlt hier, entweder nur jeweils eine Möglichkeit zu benutzen, oder vor dem Aufruf von Setscreen screenpt auf Null zu setzen. Da aber ein vorher gelaufenes Programm schon screenpt benutzt haben könnte, bleibt einem wohl nichts anderes ĂŒbrig, als screenpt bei jedem Setscreen zu löschen!

Programme, die sich in den resvector eingehĂ€ngt haben, können zwar mit 'jmp (a6)’ ins BIOS zurĂŒckspringen, doch mĂŒssen sie sich dann vorher aus resvector aushĂ€ngen, da sie sonst erneut aufgerufen werden. Daher hatte ATARI in der Dokumentation zur Beta-Test-Version des TOS 1.4 garantiert, daß ‘jmp $24(a6)’ zum Sprung ins BIOS nach der resvector-Abfrage fĂŒhrt (siehe [4]). Dies ist in der TOS 1.4-Doku wieder verschwunden, vermutlich weil sich damit nur jeweils ein Programm in resvector installieren kann. Nun wird eine andere Methode vorgeschrieben, nach der sich jedes Programm bei der Installation seiner Reset-Routine resvector und resvalid merken soll, um diese Werte, wenn es ĂŒber resvector aufgerufen wird, wieder zurĂŒckzusetzen. Dadurch können mehrere Programme auf diese Weise resident gemacht werden, allerdings mĂŒssen sie sich nun auch beim Reset aushĂ€ngen!

TOS 1.4 sollte dafĂŒr sorgen, daß Zeit und Datum zumindest beim Reset nicht verlorengehen, indem es ausnutzt, daß der Tastaturprozessor die Zeit beim Reset nicht vergißt. FĂŒr ST-Benutzer, die ĂŒber keine eingebaute Uhr verfĂŒgen, wĂ€re dies eine Erleichterung, da sie die Uhr nur einmal nach dem Einschalten stellen mĂŒĂŸten (z.B. mit dem Kontrollfeld-Accessory). Nur wenn die Uhr beim Warmstart nicht sinnvoll eingestellt ist, wĂŒrde sie auf den bekannten Default-Wert (hier 6.4.1989) gesetzt. Beim Warmstart wird also zunĂ€chst geprĂŒft, ob eine eingebaute MEGA-Uhr vorhanden ist, um ihr gegebenenfalls die PrioritĂ€t zu geben. Diese Abfrage ist falsch programmiert, so daß stets angenommen wird, daß eine MEGA-Uhr vorhanden ist, und somit niemals die Zeit aus der Tastaturprozessor-Uhr ĂŒbernommen wird. Dokumentiert ist dieses offensichtlich geplante Feature ĂŒbrigens auch nicht. Vielleicht deshalb, weil man bei ATARI den Fehler nicht finden konnte?!

     
0 USA USA
1 FRG BR Deutschland
2 FRA Frankreich
3 UK Großbritannien
4 SPA Spanien
5 ITA Italien
6 SWE Schweden
7 SWF Schweiz (Französisch)
8 SWG Schweiz (Deutsch)
9 TUR TĂŒrkei
10 FIN Finnland
11 NOR Norwegen
12 DEN DĂ€nemark
13 SAU Saudi-Arabien
14 HOL Niederlande

Abb. 2: LĂ€nderkennungen

Beim Überarbeiten der Rsconf-Funktion des XBIOS schlich sich leider ein Fehler ein, der dazu fĂŒhrt, daß der Handshake-Modus sich nicht richtig setzen lĂ€ĂŸt. Auch ATARI hat dies erkannt und bietet daher ein Patch-Programm, das diesen und einen weiteren Fehler in shel_find korrigiert. Dieser Patch liegt reset-resident von $600-$800 und wird von einem AUTO-Ordner-Programm installiert.

Die TOS-Dokumentation behauptet, das Setzen von ‘RTS/CTS’ wĂŒrde zum Abschalten jeden Handshakes fĂŒhren. FĂŒr mich sieht das eher so aus, als wĂŒrde das Setzen von ‘XON/XOFF’ zum Abschalten und das Setzen von ‘RTS/CTS‘ zum Aktivieren von ‘XON/XOFF‘ fĂŒhren, ich konnte dies aber nicht genau verifizieren. Auch das Patch-Programm liegt mir zur Zeit nicht vor, so daß ich ĂŒber dessen FunktionsfĂ€higkeit nichts sagen kann.

Kommentiertes BIOS-Listing

FĂŒr die Spezialisten unter Ihnen möchte ich noch direkt auf die Änderungen im BIOS eingehen. Generell wurden einige Optimierungen vorgenommen. Der Zugriff auf Systemvariablen wird nun noch hĂ€ufiger mit der Adressierungsart “Adreßregister indirekt mit 16-Bit-Offset” (bei gelöschtem Adreßregister) statt “absolut lang” vorgenommen. Diese Methode wird außerdem jetzt auch bei den I/O-Adressen ab $FF8000 benutzt. Daraus darf man wohl schließen, daß ATARI immer noch keinen Assembler verwendet, der die “absolut kurz”-Adres-sierung beherrscht. Weiterhin wurden jetzt einige (aber noch nicht alle) “MOVE.X #0,..’’-Befehle durch “CLR.X ..” ersetzt, und andere Kleinigkeiten wurden geschickter programmiert. Prinzipielle Optimierungen gibt es sonst keine.

Zur Analyse habe ich das BIOS bis auf die Hardcopy-Routine disassembliert und mehr oder weniger grĂŒndlich mit dem des TOS 1.2 verglichen. Im abgedruckten Listing finden sich alle Routinen, an denen inhaltliche Änderungen vorgenommen wurden (markiert durch ***). Ausgenommen sind nur einige Teile, bei denen lediglich Kleinigkeiten verĂ€ndert wurden, die hier im Text erwĂ€hnt werden. Die Tabelle umfaßt die Anfangsadressen aller wichtigen Routinen, was - zusammen mit einem BIOS-Listing des TOS 1.2, z.B. [3] - eine gute Orientierungshilfe bietet.

Noch nicht erwÀhnt habe ich bisher einige Kleinigkeiten. In der VBL-Routine wurde zweimal die Monochrommonitor-Detect-Leitung direkt am MFP abgefragt. Da sie sich zwischen den beiden Abfragen geÀndert haben könnte, wird der MFP nur noch einmal angesprochen; das zweite Mal wird der beim ersten Mal gemerkte Zustand getestet.

Bei der Ausgabe eines Zeichens ĂŒber die Centronics-Schnittstelle werden alle Interrupts gesperrt, wĂ€hrend der Strobe gesendet wird. Damit wird verhindert, daß der Strobe wesentlich lĂ€nger als ĂŒblich (zu lange?) dauern kann.

Beim Test, ob die Hardware-Uhr des MEGA ST vorhanden ist, wird nun auch ein Bus-Error abgefangen. Normalerweise gibt es zwar keinen Bus-Error, wenn auf den Adreßbereich der MEGA-Uhr zugegriffen wird, obwohl diese gar nicht vorhanden ist, aber vielleicht gibt es hier Ausnahmen oder Fehlfunktionen, denen hiermit abgeholfen werden soll.

In den Blitter-Routinen um BUdschirmtreiber die Nummer 0 bis 2) gibt es Schleifen, die warten, bis der Blitter seine Arbeit beendet hat. Bisher sahen die so aus:

... moveq #7,D4 loop: bset d4,(a5) ;Blitter Busy testen und neu starten nop bne.s loop ;-> Blitter noch beschÀftigt

Nun wird folgendes gemacht:

loop: tas (a5) ;Blitter Busy testen und neu starten nop bmi.s loop ;-> Blitter noch beschÀftigt

Der Unterschied besteht darin, daß bei tas das Testen und Setzen des Bits 7 des Zieloperanden in einem nicht-unterbrechbaren Schreib-Lese-Zugriff des 68000 erfolgt. Beim bset könnte zwischen dem Testen und Neustarten des Blitters z.B. der DMA-Chip die Kontrolle ĂŒber den Prozessor-Bus ĂŒbernehmen. Sicherer ist die Verwendung von tas auf jeden Fall: ob es auch praktische Konsequenzen hat. weiß ich nicht.

Ein letztes Wort

So das war’s fĂŒr heute. Auch wenn ich das BIOS relativ grĂŒndlich durchgearbeitet habe, ist dazu sicherlich noch nicht das letzte Wort gesprochen. Warten wir’ s also ab. Festzuhalten bleibt, daß einige wichtige Punkte geĂ€ndert oder verbessert wurden, anderes unverstĂ€ndlicherweise beim alten geblieben ist. Auch die TOS-Dokumentation ist ganz brauchbar und informativ. Ich kann das “Rainbow-TOS” nur empfehlen, da es einige ganz entscheidende Vorteile bietet, die hier nicht deutlich wurden, da sie hauptsĂ€chlich GEMDOS und Desktop betreffen. Bei dieser Gelegenheit möchte ich noch erwĂ€hnen, daß ich seit einiger Zeit auch in der MAUS-Mailbox Aachen (0241/154...) zu erreichen bin (bzw. im angeschlossenen MAUS- und FIDO-Net), falls Sie noch Fragen zur GEMDOS-Serie oder dem TOS im allgemeinen haben sollten.

Alex Esser

Literatur:

[1] Brod/Stepper: “Scheibenkleister II". MAXON 1989
[2] Esser: "EXTKEY-Tastaturbelegung einmal anders”, ST-Computer 4/89
[3] BrĂŒckmann/Englisch/Gerits: "ST intern", Data Becker 1987
[4] Esser: "Die Systemvariablen des TOS”, ST-Computer 11-12/88

;Floppy-hdv_boot FC1CC6 LINK A6,#$0000 FC1CCA MOVEM.L D6-D7,-(A7) FC1CCE JSR $FC0BD8 ;hdv_init aufrufen FC1CD4 TST.W $0004A6 ;nflops FC1CDA BEQ $FC1D12 ;-> keine Floppy: Abbruch mit 1 FC1CDC MOVEQ #$02,D7 FC1CDE MOVE.W #$0001,(A7) ;1 Sektor FC1CE2 CLR.L -(A7) ;Seite 0 und Spur 0 (*** optimiert! ***) FC1CE4 MOVE.W #$0001,-(A7) ;Sektor 1 FC1CE8 CLR.W -(A7) ;*** immer Floppy A: statt 'bootdev' *** ;(Abbruch bei 'bootdev' >=2 fehlt jetzt) FC1CEA CLR.L -(A7) ;Filler FC1CEC MOVE.L #$0000181C,-(A7) ;BIOS-Sektorpuffer FC1CF2 JSR $FC0F38 ;Floprd FC1CF8 ADDA.W #$0010,A7 FC1CFC TST.L D0 FC1CFE BNE $FC1D04 ;-> Sektor nicht lesbar: Abbruch mit 2 FC1D00 CLR.W D7 ;Boot-Sektor gelesen: kein Fehler FC1D02 BRA $FC1D10 FC1D04 TST.B $0009F8 ;WP-Status von A: (frĂŒher falsch bei B:) FC1D0A BNE $FC1D10 ;-> nein: Abbruch mit 2 FC1D0C MOVEQ #$03,D0 ;ja: Abbruch mit 3 FC1D0E BRA $FC1D38 FC1D10 BRA $FC1D14 FC1D12 MOVEQ #$01,D7 ;Abbruch mit 1 FC1D14 TST.W D7 FC1D16 BEQ $FC1D0C ;-> bisher kein Fehler FC1D18 MOVE.W D7,D0 ;Abbruch mit D7 FC1D1A BRA $FC1D38 FC1D1C MOVE.W #$0100,(A7) ;Checksumme berechnen FC1D20 MOVE.L #$0000181C,-(A7) FC1D26 BSR $FC1E2E FC1D2A ADDQ.L #4,A7 FC1D2C CMP.W #$1234,D0 FC1D30 BNE $FC1D36 ;-> Boot-Sektor nicht ausfĂŒhrbar: Abbruch mit 4 FC1D32 CLR.W D0 ;Boot-Sektor ausfĂŒhrbar: Ende mit 0 FC1D34 BRA $FC1D38 FC1D36 MOVEQ #$04,D0 ;Abbruch mit 4 FC1D38 TST.L (A7) + FC1D3A MOVEM.L (A7)+,D7 FC1D3E UNLK A6 FC1D40 RTS ;Test ob MEGA-Uhr vorhanden FC1F70 SUBA.L A1,A1 ;*** fĂŒr optimierten Zugriff *** FC1F72 MOVE.W #$FC20,A0 ;I/O-Basisadresse der MEGA-Uhr FC1F76 MOVE.L $0008(A1),D2 ;*** Bus-Error-Vektor merken *** FC1F7A MOVE.L A7,A2 ;*** SP merken *** FC1F7C MOVE.L #$FC1FB6,$0008(A1) ;*** eigene Bus-Error-Routine *** FC1F84 MOVE.B #$09,$001B(A0) ;Uhr an, Alarm aus, Bank 1 anwĂ€hlen FC1F8A MOVE.L D2,$0008(A1) ;*** alte Bus Error-Routine *** FC1F8E MOVE.W #$0A05,D0 FC1F92 MOVEP.W D0,$0005(A0) ;Alarmzeit-Minuten auf unsinnigen Wert FC1F96 MOVEP.W $0005(A0),D1 FC1F9A AND.W #$0F0F,D1 ;hat dies geklappt ? FC1F9E CMP.W D0,D1 FC1FA0 BNE $FC1FBC ;-> nein: MEGA-Uhr nicht vorhanden FC1FA2 MOVE.B #$01,$0001(A0) ;CLKOUT auf 16384 Hz FC1FA8 MOVE.B #$08,$001B(A0) ;Uhr an, Alarm aus, Bank 0 anwĂ€hlen FC1FAE MOVE.B #$00,$001D(A0) ;Testregister löschen, C=0 ! FC1FB4 RTS ;eigene Bus Error-Routine FC1FB6 MOVE.L A2,A7 ;*** SP restaurieren *** FC1FB8 MOVE.L D2,$0008(A1) ;*** Bus-Error-Vektor restaurieren *** FC1FBC ORI.B #$01,CCR ;C=1: MEGA-Uhr nicht vorhanden FC1FC0 RTS ;Gettime von IKBD FC31A8 MOVE.B #$FF,$0EAE(A5) ;Flag setzen: Zeitpaket noch nicht da FC31AE MOVE.B #$1C,D1 ;Befehl 'interrogate time-of-day clock' FC31B2 BSR $FC3460 ;Zeitpaket vom IKBD anfordern ;*** auf Zeit-Paket warten mit Timeout *** FC31B6 MOVE.L $04BA(A5),A0 FC31BA ADDA.W #$00C8,A0 ;hz_200 + 200 (Startzeit + ls) FC31BE MOVEQ #$00,D0 FC31C0 CMPA.L $04BA(A5),A0 FC31C4 BCS $FC31D0 ;-> 1s ĂŒberschritten: 0L zurĂŒckgeben FC31C6 TST.B $0EAE(A5) ;Flag testen FC31CA BNE $FC31C0 ;-> Zeitpaket noch nicht empfangen FC31CC MOVE.L $0E6C(A5),D0 ;empfangenes Paket im XBIOS-Format FC31D0 RTS ;Zeichen ĂŒber Centronics ausgeben FC3332 MOVE.W SR,D3 ;SR retten FC3334 ORI.W #$0700,SR ;IPL 7 FC3338 MOVEQ #$07,D1 ;Register 7 PSG lesen FC333A BSR $FC4086 ;(Giaccess) FC333E ORI.B #$80,D0 ;Port B auf Ausgabe schalten FC3342 MOVEQ #$87,D1 FC3344 BSR $FC4086 ;(Giaccess) FC3348 MOVE.W D3,SR ;IPL restaurieren FC334A MOVE.W $0006(A7),D0 ;auszugebendes Zeichen FC334E MOVEQ #$8F,D1 ;nach Port B schreiben FC3350 BSR $FC4086 ;(Giaccess) FC3354 MOVE.W SR,-(A7) ;*** SR retten *** FC3356 ORI.W #$0700,SR ;*** IPL 7 *** FC335A BSR $FC336C ;Strobe low setzen FC335C BSR $FC336C ;nochmal !? (= Pause) FC335E BSR $FC3366 ;Strobe high setzen FC3360 MOVE.W (A7)+,SR ;*** IPL restaurieren *** FC3362 MOVEQ #$FF,D0 ;alles klar FC3364 RTS FC3366 MOVEQ #$20,D2 ;Strobe (Bit 5) FC3368 BRA $FC40BC ;mit 'ongibit' setzen FC336C MOVEQ #$DF,D2 ;Strobe (Bit 5) FC336E BRA $FC40E2 ;mit 'offgibit' löschen ;Rsconf FC3A16 CMPI.W #$FFFE,$0004(A7) ;"Baudrate" = -2 ? FC3A1C BNE $FC3A26 FC3A1E MOVE.W $000A6E,D0 ;ja: alte Baudrate zurĂŒck FC3A24 RTS FC3A26 ORI.W #$0700,SR ;IPL 7 bis zum Ende des TRAP-Aufrufs FC3A2A LEA $000C70,A0 ;Adresse IOREC fĂŒr RS232-Eingabe FC3A30 LEA $FFFA01,A1 ;Adress MFP FC3A36 MOVEP.L $0028(A1),D7 ;UCR, RSR, TSR und UDR merken ;statt SCR, UCR, RSR und TSR FC3A3A MOVE.W $0006(A7),D0 ;Handshake-Modus FC3A3E CMP.W #$FFFF,D0 ;*** Test auf '-1' statt '<0' ! *** FC3A42 BEQ $FC3A58 ;-> nicht Ă€ndern FC3A44 MOVE.B D0,$0020(A0) ;in IOREC-VerlĂ€ngerung merken FC3A48 BEQ $FC3A54 ;-> kein Handshake FC3A4A AND.B #$3E,D0 ;*** Bits 0,6,7 löschen statt Bit 1 *** FC3A4E BEQ $FC3A54 ;-> kein Handshake FC3A50 MOVE.B #$01,D0 FC3A54 MOVE.B D0,$0020(A0) ;Handshake-Flag in IOREC setzen ;*** jetzt immer nur 0 oder 1 *** FC3A58 TST.W $0004(A7) ;Baudrate FC3A5C BMI $FC3A98 ;-> nicht Ă€ndern FC3A5E MOVEQ #$00,D0 FC3A60 MOVE.B D0,$002A(A1) ;RSR löschen FC3A64 MOVE.B D0,$002C(A1) ;TSR löschen FC3A68 MOVE.W $0004(A7),D1 ;neue Baudrate FC3A6C MOVE.W D1,$000A6E ;merken fĂŒr Rsconf(-2) FC3A72 LEA $FC3ACC,A2 FC3A78 MOVE.B $00(A2,D1.W),D0 ;Timer-Control-Wert FC3A7C LEA $FC3ADC,A2 FC3A82 MOVE.B $00(A2,D1.W),D2 ;Timer-Data-Wert FC3A86 MOVE.L D0,D1 FC3A88 MOVEQ #$03,D0 ;Timer D FC3A8A BSR $FC36AC ;Timer setzen FC3A8E MOVEQ #$01,D0 FC3A90 MOVE.B D0,$002A(A1) ;RSR: EmpfĂ€nger ein etc. FC3A94 MOVE.B D0,$002C(A1) ;TSR: Sender ein etc. FC3A98 TST.W $0008(A7) ;UCR FC3A9C BMI $FC3AA4 ;-> nicht Ă€ndern FC3A9E MOVE.B $0009(A7),$0028(A1) ;UCR setzen FC3AA4 TST.W $000A(A7) ;RSR FC3AA8 BMI $FC3AB0 ;-> nicht Ă€ndern FC3AAA MOVE.B $000B(A7),$002A(A1) ;RSR setzen FC3AB0 TST.W $000C(A7) ;TSR FC3AB4 BMI $FC3ABC FC3AB6 MOVE.B $000D(A7),$002C(A1) ;TSR setzen FC3ABC TST.W $000E(A7) ;SCR FC3AC0 BMI $FC3AC8 ;-> nicht Ă€ndern FC3AC2 MOVE.B $000F(A7),$0026(A1) ;SCR setzen FC3AC8 MOVE.L D7,D0 FC3ACA RTS ;aus Tastatur-Interrupt (nach Behandlung SHIFT/CTRL/ALT/CAPS) ;verbesserte Tastenwiederholung FC3CFA BTST #$07,D0 FC3D04 BNE $FC3D16 ;-> Taste losgelassen FC3D00 MOVE.B D0,$0E9B(A5) ;Scancode fĂŒr Tastenwiederholung FC3D04 MOVE.B $000E9E,$0E9C(A5) ;ZĂ€hler fĂŒr Wiederholschwelle init. FC3D0C MOVE.B $000E9F,$0E9D(A5) ;ZĂ€hler fĂŒr Wiederholrate init. FC3D14 BRA $FC3D48 ;Taste in Tastaturpuffer ĂŒbernehmen FC3D16 MOVE.B D0,D1 ;Taste losgelassen FC3D18 BCLR #$07,D1 ;reiner Scancode FC3D1C CMP.B $0E9B(A5),D1 FC3D20 BNE $FC3D30 ;-> andere Taste als letzte gedrĂŒckte FC3D22 MOVEQ #$00,D1 ;Tastenwiederholung aus FC3D24 MOVE.B D1,$0E9B(A5) FC3D28 MOVE.B D1,$0E9C(A5) FC3D2C MOVE.B D1,$0E9D(A5) FC3D30 CMPI.B #$C7,D0 ;HOME losgelassen ? FC3D34 BEQ $FC3D3E FC3D36 CMPI.B #$D2,D0 ;INSERT losgelassen ? FC3D3A BNE $FC3FBC ;-> weder HOME noch INSERT: fertig FC3D3E BTST #$03,$0E7D(A5) ;ALT gedrĂŒckt ? FC3D44 BEQ $FC3FBC ;-> nein: fertig FC3D48 ;Tastencode soll nach Tastaturpuffer, dazu weiter untersuchen ;Ende des Tastatur-Interrupts: Zeichen nach Tastaturpuffer ;D0: ASCII-Kode in Bits 0-7, Scan-Kode in Bits 8-15 FC3F74 MOVE.L $0000(A0),A2 ;Pufferadresse FC3F78 SWAP D0 ;Scan- u. ASCII-Kode nach Bits 16-31 FC3F7A MOVE.W #$0000,D0 FC3F7E MOVE.B $0E7D(A5),D0 ;Kbshift-Status FC3F82 SWAP D0 ;Status jetzt nach Bits 16-23 FC3F84 LSL.L #8,D0 FC3F86 LSR.W #8,D0 ;Bits 0-7: ASCII, 16-23: Scan, 24-31: Kbshift FC3F88 MOVE.L D0,D2 FC3F8A BCLR #$1C,D2 ;CAPS ignorieren FC3F8E SWAP D2 FC3F90 CMP.W #$0C53,D2 ;CTRL-ALT-DEL ? FC3F94 BEQ $FC0030 ;-> Warmstart FC3F98 CMP.W #$0D53,D2 ;CTRL-ALT-SHIFT RECHTS-DEL ? FC3F9C BEQ $FC4034 ;-> Kaltstart FC3FA0 BTST #$03,$0484(A5) ;conterm: Kbshift fĂŒr Bconin ? FC3FA6 BNE $FC3FAE FC3FA8 ANDI.L #$00FFFFFF,D0 ;nein: Kbshift löschen FC3FAE AND.L #$0000FFFF,D1 FC3FB4 MOVE.L D0,$00(A2,D1.L) ;Zeichen nach Tastaturpuffer FC3FB8 MOVE.W D1,$0008(A0) ;neuer Pufferzeiger FC3FBC RTS ;Kaltstart auslösen ;Ă€ußerst grĂŒndlich, da Hauptspeicher komplett gelöscht ;es fehlt höchstens noch das RAM im IKBD... FC4034 MOVE.W #$2700,SR ;IPL 7 FC4038 LEA $FC4050(PC),A0 ;Löschroutine ins RAM kopieren FC403C MOVE.W #$000F,D0 ;32 Worte (ein bißchen viel zwar...) FC4040 MOVE.W #$0008,A1 ;ab Adresse $8 (Bus-Error-Vektor) ! FC4044 MOVE.L (A0)+,(A1)+ FC4046 DBF D0,$FC4044 FC404A SUBA.L A5,A5 FC404C JMP $0008(A5) ;Löschroutine starten ;Speicher-Löschroutine fĂŒr Kaltstart, ins RAM ab $8 kopiert FC4050 LEA $FC4076(PC),A0 ;eigener Bus-Error-Handler FC4054 MOVE.L A0,$0008(A5) ;Anfang dieser Routine nun selbst zerstört !!! FC4058 LEA $FC4082(PC),A0 ;Beginn löschen nach dieser Routine FC405C MOVEQ #$00,D0 FC405E MOVE.L D0,D1 FC4060 MOVE.L D0,D2 FC4062 MOVE.L D0,D3 FC4064 MOVE.L D0,D4 FC4066 MOVE.L D0,D5 FC4068 MOVE.L D0,D6 FC406A MOVE.L D0,D7 FC406C MOVEM.L D0-D7,(A0) ;schnelles Löschen FC4070 ADDA.W #$0020,A0 FC4074 BRA $FC4072 ;immer weiter... bis Bus-Error kommt FC4076 MOVE.L $0004(A5),A0 ;ROM-Reset-Adresse FC407A JMP (A0) ;Reset (wirkt wie Kaltstart) durch ROM dc.w 0 ;???
Alex Esser