Code: Alles auswählen
def set_bit_for(self, attrname, condition):
setattr(self, attrname, 1 if condition else 0)
Code: Alles auswählen
def set_Z8(self, r):
self.set_bit_for('Z', r & 0xff)
Code: Alles auswählen
def set_bit_for(self, attrname, condition):
setattr(self, attrname, 1 if condition else 0)
Code: Alles auswählen
def set_Z8(self, r):
self.set_bit_for('Z', r & 0xff)
Code: Alles auswählen
class Stub(object):
CC_E = 0x80
CC_F = 0x40
CC_H = 0x20
CC_I = 0x10
CC_N = 0x08
CC_Z = 0x04
CC_V = 0x02
CC_C = 0x01
def __init__(self):
self.cc = 0
def set_z(self, r):
self.cc |= 0 if r else self.CC_Z
def set_n8(self, r):
self.cc |= (r & 0x80) >> 4
def set_nz8(self, r):
self.set_n8(r)
self.set_z(r & 0xff)
def clr_nzv(self):
self.cc &= ~(self.CC_N | self.CC_Z | self.CC_V)
def op_dec(self, _in):
out = ((_in & 255) - 1) & 255 # correction for 8 bit unsignedness
self.clr_nzv()
self.set_nz8(out)
if out == 0x7f:
self.cc |= self.CC_V
return out
Code: Alles auswählen
def signed8(x):
""" convert to signed 8-bit """
if x > 0x7f: # 0x7f == 2**7-1 == 127
x = x - 0x100 # 0x100 == 2**8 == 256
return x
def signed16(x):
""" convert to signed 16-bit """
if x > 0x7fff: # 0x7fff == 2**15-1 == 32767
x = x - 0x10000 # 0x100 == 2**16 == 65536
return x
Code: Alles auswählen
unsigned out = in - 1
Code: Alles auswählen
unsigned out = in - 1
Danke für den Hinweis. Das könnte man doch auch so lösen:jerch hat geschrieben:Was mir noch aufgefallen ist - in Deiner Makroübertragung von `set_z` und `set_n8` fehlt das ODER mit dem derzeitigen Flagwert, heisst, ist eines der Flags auf 1, bleibts 1.
Code: Alles auswählen
def set_V8(self, a, b, r):
if self.V == 0:
self.V = 1 if (a ^ b ^ r ^ (r >> 1)) & 0x80 else 0
Code: Alles auswählen
def set_V8(self, a, b, r):
if self.V == 0 and (a ^ b ^ r ^ (r >> 1)) & 0x80:
self.V = 1
Das habe ich mittlerweile behoben. Jede Instruction-Methode bekomme nun mit ea die effektive Adresse und je nach oppcode mit m den Speicherinhalt.jens hat geschrieben:Mir ist aufgefallen, das ich wohl grundlegenden Fehler gemacht habe: Bei mir ist z.Z. ea nicht immer die "effective Address" sondern auch mal direkt der Speicherinhalt. Aber je nach OpCode braucht mal mal das eine oder mal das andere oder beide.
Code: Alles auswählen
10 ' MACHINE CODE LOADER
20 READ LA ' LA = LOAD ADDRESS (START OF PROGRAM)
30 READ EA ' EA = ADDRESS OF FIRST INSTRUCTION
40 PA = EA 'TO BE EXECUTED
50 READ HB$ ' HEX CONSTANTS
60 IF HB$="END" THEN 100
70 POKE PA,VAL("&H"+HB$) ' POKE VALUE INTO MEMORY
80 PA = PA + 1 ' INCREMENT ADDRESS
90 GOTO 50
100 PRINT "AUTORUN WITH EXEC";EA;":"
105 PRINT "-------------------------------"
110 EXEC EA ' AUTORUN
114 PRINT
115 PRINT "-------------------------------"
120 PRINT "END ADDRESS:"; PA-1
130 PRINT "RUN AGAIN WITH EXEC";EA
149 ' LOAD ADDRESS:
150 DATA 20001
159 ' EXECUTE ADDRESS:
160 DATA 20001
165 ' MACHINE CODE IN HEX
170 DATA 34,12 ' PSHS A,X ; Save registers A, X
180 DATA CC,58,58 ' LDD $5858 ; $5858 == 22616
190 DATA BD,95,7A ' JSR 38266 ; outputs the decimal value of D register
260 DATA 35,92 ' PULS A,X,PC ; Restore and return
270 DATA END
Kenne ich. Hab mir schon einiges angesehen. Aber richtig brauchbares habe ich noch nicht gefunden. Die meisten Sachen sind zimlich alt. Teilweise noch für DOS.jerch hat geschrieben:@jens:
Ist denn hier --> http://koti.mbnet.fi/~atjs/mc6809/ nichts Brauchbares dabei?
Der Absatz "How do I optimize C code?" ist nicht völlig auf systemnahe Sprachen wie C beschränkt, falls das so gemeint war. Wenn man zum Beispiel oft Berechnungen mit Vielfachen von 2 hat, dann kann man die durchaus zu Bitoperationen umschreiben. Das spart auch in CPython ein bißchen Ausführungszeit ein. Und der erste dort genannte Punkt, der die Nutzung eines Profilers zwecks Codeanalyse vorschlägt, ist ebenfalls in Python umsetzbar. Klar, die Verwendung spezieller C-Schlüsselworte trifft natürlich nur auf C zu.jens hat geschrieben:was Grundlegendes zum Thema Wie man einen Emulator programmiert hab ich bei http://fms.komkon.org/EMUL8/HOWTO.html gefunden. Interessant, wenn man den ganzen "wir in C optimieren" Teil weg läßt.
Wenn man einen Emulator programmiert, beziehungsweise wenn jemand den Quelltext für einen Emulator liest, kann man davon ausgehen, dass die Bitoperationen sitzen und verstanden werden, also kann man da auch schieben statt Punktrechnungen zu machen, aber in „normalen” Programmen würde ich mir so etwas verkneifen. Es geht auf Kosten der einfache(re)n Verständlichkeit und bringt bei modernen Maschinen/Compilern keinen Vorteil.@jonshiring hat geschrieben:In C++, everytime someone writes ">> 3" instead of "/ 8", I bet the compiler is like, "OH DAMN! I would have never thought of that!"
Das ist bei mir nicht wirklich der Fall. Deswegen möchte ich das ehr vermeidenBlackJack hat geschrieben:Wenn man einen Emulator programmiert, beziehungsweise wenn jemand den Quelltext für einen Emulator liest, kann man davon ausgehen, dass die Bitoperationen sitzen und verstanden werden, also kann man da auch schieben statt Punktrechnungen zu machen, aber in „normalen” Programmen würde ich mir so etwas verkneifen.
Das ist ja fast wie der Wunsch Romane zu verfassen, aber bitte ohne Wörter zu benutzen. Ich hab dir schon vor einigen Wochen nahegelegt, dass du dich damit beschäftigen solltest. Das wären vielleicht ein oder zwei Abende Arbeit gewesen und hätte dir wahrscheinlich schon mehr Zeit gespart. Manchmal braucht es eben ein wenig Wissen und Bit-Operationen sind nun alles andere als Magie.jens hat geschrieben:Das ist bei mir nicht wirklich der Fall. Deswegen möchte ich das ehr vermeidenBlackJack hat geschrieben:Wenn man einen Emulator programmiert, beziehungsweise wenn jemand den Quelltext für einen Emulator liest, kann man davon ausgehen, dass die Bitoperationen sitzen und verstanden werden, also kann man da auch schieben statt Punktrechnungen zu machen, aber in „normalen” Programmen würde ich mir so etwas verkneifen.
Code: Alles auswählen
import time
def measure_division(number, divisor, num_loops=10**7):
before = time.time()
for _ in xrange(num_loops):
number // divisor
after = time.time()
return after - before
def measure_right_shift(number, num_bits, num_loops=10**7):
before = time.time()
for _ in xrange(num_loops):
number >> num_bits
after = time.time()
return after - before
Code: Alles auswählen
>>> import shiftperf
>>> 0x150 // 8
42
>>> 0x150 >> 3
42
>>> shiftperf.measure_right_shift(0x150, 3) / shiftperf.measure_division(0x150, 8)
0.7201051550896614
>>> shiftperf.measure_right_shift(0x150, 3) / shiftperf.measure_division(0x150, 8)
0.7211107141874019
>>> shiftperf.measure_right_shift(0x150, 3) / shiftperf.measure_division(0x150, 8)
0.7240534444336117
Code: Alles auswählen
In [6]: %timeit 0x150 // 8
10000000 loops, best of 3: 35 ns per loop
In [7]: %timeit 0x150 >> 3
10000000 loops, best of 3: 35.1 ns per loop