Stunde 126
Disassembled: 215.156 / 1.048.576 Bytes (20,519%)
Gehört: Suffer Like G Did - Raspberry EP, Kuniaki Haishima - Monster OST
Heut schreib ich meinem Brüderle eine E-Mail. Danach werde ich vielleicht noch ein wenig die Log weiterlesen, wenn es die Zeit zulässt.
~~~
Nach vierzig Minuten habe ich dann das grobe *irgendwas* Konzept fertig. Hundertpro wird das beim ersten Lauf nicht sauber funktionieren:
Code: Alles auswählen
// DEFINE
uint8_t memory[0x1000];
uint8_t InputCounter;
uint8_t OutputCounter;
uint8_t NextFEBPos;
uint8_t NextFEBContent;
unit8_t NextFEBStelle;
uint8_t score;
uint8_t hiscore;
uint16_t hiscoreaddress;
uint8_t AbgleichCounter;
unit8_t OutputByte;
uint16_t RamIndex;
uint16_t SearchRamIndex;
// PREP
InputCounter = 0;
OutputCounter = 5;
NextFEBPos = 4;
NextFEBContent = 0;
for RamIndex = 0 to 0x0fff
memory[RamIndex] = 0;
RamIndex = 0x0ffe;
OutputDatei[0] = filesize[InputDatei] & 0xff;
OutputDatei[1] = filesize[InputDatei] & 0xff00 >> 8;
OutputDatei[2] = 0;
OutputDatei[3] = 0;
//EXEC
Exec:
NextFEBStelle = 0;
score = 1;
hiscore = 0;
hiscoreaddress = 0;
for SearchRamIndex = 0 to 0xfff
begin
if memory[SearchRamIndex] = Inputdatei[InputCounter] then
begin
// taucht die in der InputDatei vor uns liegende Kette von Bytes schon im memory auf?
for AbgleichCounter = 1 to 0x12
begin
if memory[(SearchRamIndex+AbgleichCounter) & 0xfff] = Inputdatei[(InputCounter+AbgleichCounter) & 0xfff] then
score = score + 1;
else AbgleichCounter = 0x20 // exit Abgleich
end;
if score > hiscore then
begin
hiscore = score;
hiscoreaddress = memory[SearchRamIndex];
end;
end;
end;
if hiscore < 3 then
begin // Standardfall
memory[RamIndex++] = InputDatei[InputCounter];
OutputDatei[OutputCounter++] = InputDatei[InputCounter++];
NextFEBContent = NextFEBContent + 1 << NextFEBStelle;
end;
else
begin // Sonderfall
OutputDatei[OutputCounter++] = highscoreaddress & ff;
OutputDatei[OutputCounter++] = highscoreaddress &f00 >> 4 + (hiscore - 3);
for AbgleichCounter = 0 to hiscore
memory[RamIndex++] = Inputdatei[InputCounter++];
NextFEBStelle = NextFEBStelle + 1;
end;
if NextFEBStelle = 8 then
begin
OutputFile[NextFEBPos] = NextFEBContent;
NextFEBStelle = 0;
NextFEBContent = 0;
NextFEBPos = OutputCounter++;
end;
if InputCounter < filesize[inputcounter] then
goto Exec
Ich bin mal gespannt, aber ich gehe davon aus, dass das noch ein ziemlich fieses Bugtracking geben wird, zu dem mein Bruder vermutlich keine Lust haben wird und mich auf kurz oder lang dazu bringen wird, mir wieder Qt zu installieren und den Kram, den er mir einmal in anständiges C(++) übersetzt hat, selbst zu kompilieren.
Mag sein, dass das einen gewissen Lerneffekt haben mag, aber wirklich effektives Arbeiten ist das für mich nicht, wenn ich dann auch noch nebenbei C lernen soll. :/
Anywaaays! Ich mache mal mit der Logdatei weiter. Nur, um mir Bestätigung zu holen, dass das alles so funktioniert, wie ich das dachte.
~~~
Stunde rum, Resümee:
Meine Güte, ja, es funktioniert so, wie ich es mir dachte.
Ich habe gerade noch eine Erklärung in Englisch mit Ach und Krach in der ASM-Datei versucht.
Folgendes Prinzip:
Am Anfang wird ein großer Speicher im WRAM gecleart. Alle Bytes, die ausgegeben werden, werden dort genauso mitgeschrieben. Sobald sich drei oder mehr Bytes nach einem Muster wiederholen, dass schon einmal dagewesen ist, wird in die komprimierten Daten ein Hinweis gemacht, dass angibt, von welcher Stelle im WRAM wie viele Bytes kopiert werden sollen.
Beispiel:
Dekomprimiert: 00 01 00 01 00 02 00 01 00 01 00 03 04 05
Da hieße es dann: 00 01, wiederhole drei Bytes, beginnend beim hiererstgenannten (das heißt, der erste Byte, der gesetzt wird, ist gleichzeitig der letzte, der "wiederaufgegriffen" und neu eingesetzt wird"), 02, wiederhole fünf Bytes, beginnend beim erstgenannten, 03.
Komprimiert wären das dann 00 01 ?? ?? 02 ?? ?? 03 04 05
Statt vierzehn, nur zehn Byte.
Na gut, eigentlich elf Byte.
Denn: Woran soll das Ding erkennen, ob es den Byte jetzt so ausgeben soll, wie er da steht, oder der Byte und sein Nachbar diese Sonderfall-Adress- und -Längen-Daten sind?
Es stehen immer wieder Bytes dadrin, deren Bits darüber Auskunft geben. Diese Bits werden der Reihe nach untersucht. 1 ist für einen normalen Byte, 0 für die Spezi-Doppelbytes. Sobald alle Bits durchsind, wird der nächste Byte automatisch als so ein Info-Byte interpretiert.
Für obiges Beispiel hieße das: Zwei normale, ein Spezi, ein normaler, ein Spezi, drei Normale... 1110.1011. Der Infobyte wäre $EB.
Coole Sache. Das heißt, nächstes Mal kann ich mich etwas anderem widmen. Weheeey!
