-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathgatodecodercolsdownlswap.cpp
69 lines (55 loc) · 1.95 KB
/
gatodecodercolsdownlswap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "gatodecodercolsdownlswap.h"
#include <QDebug>
/* NEC uCOM4 micros use a format much like cols-downl
* except that the 128 byte pages periodically swap order.
* This only works in 8-bit mode.
*
* The first and secoond page come first.
* Then the fourth before the third.
* Then the fifth and sixth.
* Then the eighth and seventh.
*/
GatoDecoderColsDownLSwap::GatoDecoderColsDownLSwap(){
name="cols-downl-swap";
}
QByteArray GatoDecoderColsDownLSwap::decode(GatoROM *gr){
uint32_t adr=0, vadr=0; //Physical and virtual address.
QByteArray ba, vba, empty; //Physical and virtual bytes.
int wordsize=gr->wordsize;
gr->eval();
//We might be dynamic, but we still don't want to crash.
if(wordsize!=8 || gr->outputcols%wordsize!=0) return ba;
int skip=gr->outputcols/wordsize;
//Each row contains sixteen 8-bit words.
//We calculate that dynamically to be more generic.
for(unsigned int word=0; word<(gr->outputcols/wordsize); word++){
for(unsigned int row=0; row<gr->outputrows; row++){
uint32_t w=0;
for(int bit=wordsize-1; bit>=0; bit--){
GatoBit *B=gr->outputbit(row,bit*skip+word);
assert(B); //If this fails, we're about to crash.
//Update target address and mask.
B->adr=vadr;
B->mask=1<<bit;
if(B->getVal())
w|=B->mask;
}
ba.append(w&0xFF);
/* The virtual address is the same as the physical,
* except when we are swapping.
*/
vadr=++adr;
if(adr&0x100) vadr=adr^0x80;
}
}
//ba is in the physical order, so we need to swap it.
for(unsigned int adr=0; adr<ba.length(); adr++){
vadr=adr;
if(adr&0x100) vadr=adr^0x80;
if(ba.length()>vadr)
vba.append(ba[vadr]);
else
return empty;
}
return vba;
}