Einzelnen Beitrag anzeigen
Alt 26.11.2008, 10:13   #1
leecher
Moderator
Pause+Enter Patch (siehe Project)

Wir OpenAccess-User kennen ja alle das Problem:

Wenn man oavision in der NTVDM unter windows startet, dann geht die CPU-Last auf 100% und oa tut solange nix, bis man PAUSE + ENTER drückt, dann startet es. Ein lästiges Problem, was leider auch im dosemu unter Linux auftritt. Der Workaround mit PAUSE+RETURN geht zwar unter Windows, unter Linux über ein Terminal funktioniert das mit dem Pause aber leider nicht mehr.

Grund genug, das Problem zu analysieren und zu beheben.


Ich habe mich also mit meinem Debugger mal auf die Suche gemacht und bin dabei auf folgende Schleife gestoßen, in die ich eigentlich immer reingekommen bin. Ich habe sie rudimentär kommentiert, damit man hoffentlich auch als Assembler-Unkundiger ungefähr versteht was hier los ist:

Code:
cs:1B28 BB0100         mov    bx,0001
cs:1B2B 32E4           xor    ah,ah
cs:1B2D CD1A           int    1A    ; Get System Time 
cs:1B2F 52             push   dx
cs:1B30 8BC3           mov    ax,bx
cs:1B32 B9F10A         mov    cx,0AF1
cs:1B35 E2FE           loop   1B35    ; AF1mal einfach hier loopen
cs:1B37 48             dec    ax
cs:1B38 75F8           jne    1B32    ; Schleife je nach Systemtime
cs:1B3A 32E4           xor    ah,ah
cs:1B3C CD1A           int    1A    ; Nochmal systemtime holen
cs:1B3E 59             pop    cx
cs:1B3F 3D0100         cmp    ax,0001    ; Mitternacht vergangen?
cs:1B42 74E4           je     1B28    ; ..dann nochmal
cs:1B44 2BD1           sub    dx,cx    ; Differenz errechnen
cs:1B46 83FA02         cmp    dx,0002
cs:1B49 7307           jnb    1B52    ; >=2, dann ok
cs:1B4B F8             clc
cs:1B4C 43             inc    bx
cs:1B4D 73DC           jnb    1B2B
cs:1B4F BBFFFF         mov    bx,FFFF    ; Return -1, Fehlgeschlagen
cs:1B52 36891E3219     mov    ss:[1932],bx
cs:1B57 CB             retf        ; Und Ende
Aufgefallen ist mir, dass, sobald ich in den Debugger reingebreakt bin und dann den Programmfluss fortgesetzt habe, OA relativ schnell da war. Nur wenn mans einfach so aufgerufen hat wieder die hohe CPU-Auslastung. Denkt man dann an den Workaround mit PAUSE+ENTER wird einem schnell klar, was hier abläuft: Drückt man PAUSE, hält man temporär den Programmfluss an, drückt man eine beliebige Taste setzt man ihn wieder fort. Durch das kurzfristige Anhalten bewirkt man, dass zwischen den beiden "Get System Time" - Aufrufen eine Unterbrechung entsteht. Wenn wir dann noch die Geschwindigkeit heutiger Rechner und der Rechner vergleichen, für die OA entwickelt wurde kommt man zu dem Schluss: Die Differenz ist auf modernen Systemen und in der VDM ziemlich lange <2, was bewirkt, dass die Funktion sehr lange loopt.

Das Umgehen des Problems ist dann auch schnell mit einem 1-Byte-Patch getan:

PHP-Code:
1Open Access IV beenden
2
Öffnet die OA4.SPI oder die CMP.SPI je nachdem was ihr patchem wollt 
mit einem Texteditor der auch HEX Suche kann

3Sucht nach3D 01 00 74 E4 2B D1 83 FA 02 und ändert den Wert 
ganz hinten von 02 auf 00 

Update 28.11.2008:
Das Ganze funktioniert übrigens auch für die Runtime CMP.SPI. Der Patcher berücksichtigt nun auch die Runtime. Assembler-Sourcecode vom Patcher gibt's auf Anfrage...

Doch halt! Update 07.12.2008:
Wie Leser Gerd unten richtig bemerkt hat, funktioniert dann das Music-Kommando nicht mehr richtig, da die verbleibende Wartezeit 1 ist!
Für einene saubereren Workaround also bitte unten meinen Artikel lesen.
Ich habe meinen angehängten Patcher in patch.zip entsprechend auf die neue Methode aktualisiert, dieser Patch überspringt nicht nur die lästige Warteroutine am Programmanfang sondern korrigiert auch das Timing-Verhalten.
Bitte vor dem Patchen die OA4.SPI sichern, sicher ist sicher...!

Beim Debuggen ist mir dann auch aufgefallen, warum oa4.exe im Vergleich mit oavision relativ langsam läuft:

OA4 verwendet zur optimierten Bildschirmausgabe Informationen über den Vertical Retrace aus dem VGA I/O Port 3DAh. Dies funktioniert zwar auf einer echten VGA-Karte sehr schnell, wenn man das Ding allerdings in der NTVDM laufen lässt kann man den I/O Port nicht direkt abfragen und die VDM muss das Syncen übernehmen, was sehr langsam ist. Daher die verzögerte Ausgabe. Wen's interessiert kann sich The vertical retrace durchlesen. OAVISION verwendet hingegen einen Videotreiber, welcher die Ansteuerung übernimmt und da fällt das Ganze dann weg.
Der Code ist im Prinzip folgender:
Code:
cs:2BEA BADA03         mov    dx,03DA       ; I/O Port 03DA
cs:2BED 2E8B0E202C     mov    cx,cs:[2C20]
cs:2BF2 AD             lodsw
cs:2BF3 8BD8           mov    bx,ax
cs:2BF5 EC             in     al,dx         ; Einlesen
cs:2BF6 D0D8           rcr    al,1          ; Sync?
cs:2BF8 72FB           jb     2BF5          ; Nein, dann nochmal.
cs:2BFA EC             in     al,dx
cs:2BFB D0D8           rcr    al,1
cs:2BFD 73FB           jnb    2BFA
Wer auch dieses "Problemchen" beheben will: Es reicht, den Sprung in der ersten einfach
einfach auszuNOPpen.
Also für die Hexeditor-Benutzer: Suche nach
Code:
AD 8B D8 EC D0 D8
und ersetze die zwei folgenden Bytes
Code:
72 FB
durch
Code:
90 90
.
Bequemer geht's wieder mit angehängtem Patch vdmpatch.zip. Auf einem echten DOS-System bringt dieser Patch aber eher Nachteile, also nur für Benutzer interessant, die OA4 in einer VDM z.B. unter Windows oder Linux betreiben.
Nachdem man das Problem mit oavision ja umschiffen kann ist der Patch wahrscheinlich hauptsächlich für Benutzer der Runtime CMP.SPI interessant.

Update 04.12.2008:
Asche auf mein Haupt! Der alte Patcher hatte einen Fehler und hat die falschen Bytes an die falsche Stelle gepatcht.. Sowas Dummes, ist mir erst jetzt aufgefallen. Ich habe den vdmpatch.zip aktualisiert, jetzt sollte es passen. Als Entschädigung kann er dafür auch OA3 patchen.

Einen weiteren Tip gibt's dann zum Abschluss noch für die Verwendung von OA4 mit Dosemu:

Leider verbraucht das Programm 100% CPU-Leistung in dosemu, weil es ja für dne Realmode ausgelegt ist und daher die CPU normalerweise für sich beanspruchen und schön die Tastatur pollen kann. Nachdem das aber doch einiges an Saft verbraucht und eigentlich nicht nötig ist gibt's auch dafür nen schönen Workaround (ist nicht von mir, aber die Idee ist gut):

auslast.zip

Einfach die auslast.com vor dem Start von OA ausführen. Das Ding hängt sich in den Tastaturinterrupt 0x16 als TSR hinein und setzt ein paar Release Current Virtual Machine Time-Slice Kommandos ab, was die VM zwingt, den Timeslice aufzugeben. Das funzt auch im dosemu, nicht nur unter Windows (dort hat man das Problem ja nicht) und senkt die CPU-Last merklich.

Soda, genug OA-Optimierung für heute

EDIT: Die Patcher findet ihr im Download Bereich !
Miniaturansicht angehängter Grafiken
Klicken Sie auf die Grafik für eine größere Ansicht

Name:	hexadresse.jpg‎
Hits:	43
Größe:	168.9 KB
ID:	221   Klicken Sie auf die Grafik für eine größere Ansicht

Name:	hexadresse_patch.jpg‎
Hits:	33
Größe:	146.5 KB
ID:	222  
leecher ist offline   Mit Zitat antworten