FSUB
Anmerkung: Dieser Artikel beschreibt die numerische FSUB-Routine im BASIC-ROM, die allen Subtraktionen im BASIC V2 des Commodore 64 zugrundeliegt.
Name: | FSUB | ||||||
Beschreibung: | Fließkommazahl aus dem Speicher nach ARG holen, dann FAC von dieser Zahl subtrahieren und das Ergebnis in FAC speichern | ||||||
Einsprungpunkt: | $B850 / 47184 | ||||||
Übergebene Argumente: | |||||||
Akkumulator: | Adresse Minuend A (Low-Byte) | ||||||
Y-Register: | Adresse Minuend A (High-Byte) | ||||||
Sonstige: | FAC = Subtrahend B | ||||||
Rückgabe-Werte: | |||||||
Sonstige: | FAC = Ergebnis der Subtraktion A-B, ARG = Minuend A |
FSUB — manchmal auch als MEMMIN[1], SUBMEM[2], M-SUB[3] oder einfach als Minus[4] bezeichnet — holt eine Fließkommazahl aus dem Speicher des C64 in das Fließkommaregister ARG, subtrahiert dann den bereits im Fließkommaregister FAC befindlichen Wert von dieser Zahl und speichert das Ergebnis wieder in FAC. Die Speicheradresse dieses Minuenden wird im Akkumulator (Low-Byte) und im Y-Register (High-Byte) übergeben. Die Zahl muss im kompakten 5 Byte-Format vorliegen, wie es zum Speichern von REAL-Variablen verwendet wird. Es können sowohl Werte im RAM als auch Konstanten im BASIC-ROM adressiert werden.
Nach dem Aufruf steht in FAC das Ergebnis der Subtraktion, während ARG weiterhin die aus dem Speicher gelesene Zahl enthält. Diese kann dann für nachfolgend aufgerufene Numerik-Routinen weiter verwendet werden. Ist das Ergebnis der Subtraktion zu groß für die Fließkommadarstellung des C64, so löst FSUB einen ?OVERFLOW ERROR aus. In diesem Fall ist FAC anschließend undefiniert, während ARG noch den Wert aus dem Speicher enthält.
Neben dem Inhalt der Fließkommaregister FAC und ARG ändert FSUB auch das Rundungsbyte des Hilfspuffers FAC#3 an Adresse 86/$56. Die innerhalb von FSUB aufgerufene CONUPK-Routine überschreibt zudem den Hilfszeiger an den Adressen 34/$22 (Low-Byte) und 35/$23 (High-Byte).
Algorithmus[Bearbeiten | Quelltext bearbeiten]
FSUB implementiert keine eigenständige Subtraktion, sondern negiert nur den im Fließkommaregister FAC gespeicherten Wert und springt dann zur ROM-Routine FADDT, die die eigentliche Berechnung als Addition von ARG und (-FAC) durchführt. Zuvor bereitet FSUB noch den Aufruf von FADDT in gleicher Weise vor, wie dies üblicherweise von der Routine CONUPK erledigt wird. Hierzu werden die Vorzeichen von ARG und (negiertem) FAC verglichen und das Ergebnis im höchstwertigen Bit von Adresse 111/$6F gespeichert (0: Vorzeichen sind gleich, 1: Vorzeichen sind verschieden). Zuletzt lädt FSUB noch den Exponenten des Fließkommaregisters FAC in den Akkumulator und setzt dadurch das Zero-Flag genau dann, wenn FAC gleich 0 ist.
Laufzeitverhalten[Bearbeiten | Quelltext bearbeiten]
Der von FSUB mitverwendete Algorithmus sowie das Laufzeitverhalten sind ausführlich in der Beschreibung der ROM-Routine FADD dokumentiert. Zu den dort angegebenen Laufzeiten ist lediglich noch die Rechenzeit für das Negieren von FAC (20 Systemtakte) hinzuzurechnen.
Weblinks[Bearbeiten | Quelltext bearbeiten]
- Disassembly von FSUB/$B850 auf All About Your 64
- CodeBase 64: Floating Point Math
- C64 BASIC & KERNAL ROM Disassembly von Michael Steil
- C64OS: Floating Point Math from BASIC
Quellen[Bearbeiten | Quelltext bearbeiten]
- ↑ Lothar Englisch: Das Maschinensprachebuch für Fortgeschrittene zum Commodore 64, S. 67
- ↑ Florian Müller: C64 für Insider, S. 460
- ↑ Winfried Kassera/Frank Kassera: C64 Programmieren in Maschinensprache, S. 299
- ↑ Said Baloui/Rolf Brückmann/Lothar Englisch/Jacques Felt/Ralf Gelfand/Klaus Gerits/Darko Krsnik: Das neue Commodore 64 Intern Buch, S. 626