Since the Gameboy's processor, the LR35902, is a hybrid of the Z80 and the Intel 8080, keeping in mind that the Z80 and the Intel 8080 were designed to be mostly cross-compatible anyways, could anything that has a Z80 processor run opcodes that were meant for the LR35902? I was wondering not because I was hoping to use my TI84 to play Pokemon in study hall.
EDIT: I am aware that I would have to reprogram the controls, and probably the way that the game accesses RAM, but I'd rather just do that than port the whole game over.
The Z-80 instruction set is a superset of the 8080 instruction set. The LR35902 shares much in common with the 8080 but replaces some 8080 instructions with different ones and extends the instruction set in some different directions than the Z-80. The LR35902 is not compatible with the Z-80 nor is it compatible with the 8080.
You would have to find all uses of incompatible instructions and replace them with patches that provide the same functionality. Since the TI84 is much faster than the original GameBoy CPU the extra time taken will not be a problem and it will be easy to code replacements for the instructions themselves. The disassembly of the ROM and separating code from data will be time consuming.
However, you could take an existing GameBoy emulator and instrument it to record the locations of instructions it executes that are different on the Z-80. Playing the game extensively should find most of the places where the code must be patched.
For a quick overview see this chart of LR35902 instructions and compare with the Z-80. You'll also need this description of LR35902 instructions.
Here's a brief rundown instruction opcode differences between the LR35902 and the Z-80.
Opcode LR35902 Z-80
------ -------------- ----------
F2 LD A,(C) JP P,nn
E2 LD (C),A JP NV,nn
EA LD (nn),A JP V,nn
FA LD A,(nn) JP M,nn
3A LDD A,(HL) LD A,(nn)
32 LDD (HL),A LD (nn),A
2A LDI A,(HL) LD HL,(nn)
22 LDI (HL),A LD (nn),HL
08 LD (nn),SP EX AF,AF'
E0 LDH (n),A RET NV
F0 LDH A,(n) RET P
F8 LD HL,(SP+e) RET M
E8 ADD SP,e RET V
CB 3x SWAP r SL1 r (undocumented)
10 STOP DJNZ
D9 RETI EXX
It is a small help that LD A,(nn) and LD (nn),A are available on both and simply use different opcodes.
Related
I need a helping hand in order to understand the following assembly instruction. It seems to me that I am calling a address at someUnknownValue += 20994A?
E8 32F6FFFF - call std::_Init_locks::operator=+20994A
Whatever you're using to obtain the disassembly is trying to be helpful, by giving the target of the call as an offset from some symbol that it knows about -- but given that the offset is so large, it's probably confused.
The actual target of the call can be calculated as follows:
E8 is a call with a relative offset.
In a 32-bit code segment, the offset is specified as a signed 32-bit value.
This value is in little-endian byte order.
The offset is measured from the address of the following instruction.
e.g.
<some address> E8 32 F6 FF FF call <somewhere>
<some address>+5 (next instruction)
The offset is 0xFFFFF632.
Interpreted as a signed 32-bit value, this is -0x9CE.
The call instruction is at <some address> and is 5 bytes long; the next instruction is at <some address> + 5.
So the target address of the call is <some address> + 5 - 0x9CE.
If you are analyzing the PE file with a disassembler, the disassembler might had given you the wrong code. Most malware writer uses insertion of E8 as anti-disassembly technique. You can verify if the codes above E8 are jump instructions where the jump location is after E8.
I'm confused about the RISC-V ABI Register Names. For example, Table 18.2 in the "RISC-V Instruction Set Manual, Volume I: User-Level ISA, Version 2.0" at page 85 specifies that the stack pointer sp is register x14. However, the instruction
addi sp,zero,0
is compiled to 0x00000113 by riscv64-unknown-elf-as (-m32 does not make a difference). In binary:
000000000000 00000 000 00010 0010011
^imm ^rs1 ^f3 ^rd ^opcode
So here sp seems to be x2. Then I googled a bit and found the RISC-V Linux User's Manual. This document states that sp is x30.
So what is it? Are there different ABIs? Can I set the ABI with a command line option to riscv64-unknown-elf-*? Is there a comprehensive table somewhere?
The stack pointer is now x2.
Here is the current ABI documentation, which has been moved out of the User-Level ISA specification, which now contains that same link.
The ABI was modified to better accommodate the new RISC-V compressed spec, which puts the 8 most-used registers next to each other in x8-x15.
Note: do not trust ANY non riscv.org webpage. Quan Nguyen makes this clear in his introduction that the "RISC-V Linux User's Manual" is for documenting the porting process and that accuracy is NOT guaranteed.
I have an assembly program that has the following code.
This code compiles fine for a intel processor. But, when I use a PPC (cross)compiler, I get an error that the opcode is not recognized. I am trying to find if there is an equivalent opcode for PPC architecture.
.file "assembly.s"
.text
.globl func64
.type func64,#function
func64:
rdtsc
ret
.size func64,.Lfe1-func64
.globl func
.type func,#function
func:
rdtsc
ret
PowerPC includes a "time base" register which is incremented regularly (although perhaps not at each clock -- it depends on the actual hardware and the operating system). The TB register is a 64-bit value, read as two 32-bit halves with mftb (low half) and mftbu (high half). The four least significant bits of TB are somewhat unreliable (they increment monotonically, but not necessarily with a fixed rate).
Some of the older PowerPC processors do not have the TB register (but the OS might emulate it, probably with questionable accuracy); however, the 603e already has it, so it is a fair bet that most if not all PowerPC systems actually in production have it. There is also an "aternate time base register".
For details, see the Power ISA specification, available from the power.org Web site. At the time of writing that answer, the current version was 2.06B, and the TB register and opcodes were documented at pages 703 to 706.
When you need a 64-bit value on a 32-bit architecture (not sure how it works on 64-bit) and you read the TB register you can run into the problem of the lower half going from 0xffffffff to 0 - granted this doesn't happen often but you can be sure it will happen when it will do the most damage ;)
I recommend you read the upper half first, then the lower and finally the upper again. Compare the two uppers and if they are equal, no problemo. If they differ (the first should be one less than the last) you have to look at the lower to see which upper it should be paired with: if its highest bit is set it should be paired with the first, otherwise with the last.
Apple has three versions of mach_absolute_time() for the different types of code:
32-bit
64-bit kernel, 32-bit app
64-bit kernel, 64-bit app
Inspired by a comment from Peter Cordes and the disassembly of clang's __builtin_readcyclecounter:
mfspr 3, 268
blr
For gcc you can do the following:
unsigned long long rdtsc(){
unsigned long long rval;
__asm__ __volatile__("mfspr %%r3, 268": "=r" (rval));
return rval;
}
Or For clang:
unsigned long long readTSC() {
// _mm_lfence(); // optionally wait for earlier insns to retire before reading the clock
return __builtin_readcyclecounter();
}
I've found this dictionary by William Whitaker on the Internet and I like its parsing capabilities. But the output doesn't fit for me.
The issue (challenge for me):
Given an input form such as "audiam", the program returns the following output (plain text):
audi.am V 4 1 PRES ACTIVE SUB 1 S
audi.am V 4 1 FUT ACTIVE IND 1 S
audio, audire, audivi, auditus V (4th) [XXXAO]
hear, listen, accept, agree with; obey; harken, pay attention; be able to hear;
But I just want to receive the following text output (same input: audiam):
audiam=audio, audire, audivi, auditus
That is:
InputWord=Dictionary_Forms
So some pieces of information are needless for me.
How can I change the output of this program by modifying the Ada code?
I don't have any Ada knowledge, but I know Delphi/Pascal so it's quite easy to understand the code, isn't it? So the parts causing the text output seem to be the TEXT_IO.PUT(...) statements, right? They're all called in list_package.adb so this is probably the source file to look at.
What has to be changed in particular?
The full Ada 95 source code of this program is available on this page.
I hope some of you are able to understand Ada 95 code. Thank you very much in advance!
My compiling problems:
For use on a windows machine, I downloaded MinGW and tried to compile the source files using "MinGW Shell". But this was my input and the shell's reponse:
Compiling with the latest Cygwin version:
When I compile the program using the latest version of Cygwin, there is no error message:
There is even an .exe file which is created. Its size is 1.6 MB (1,682,616 bytes). But when I open it, it closes right away. What has gone wrong?
William Whitaker's Words is a handy tool. You may be able to find a version already built for your platform. I've not changed the code, but you can alter some things using various parameters. It's even hosted online. If you get an Ada compiler, I've included the last Makefile I used. It's a little thin on abstraction, but it includes the essential steps to compile the program and utilities, along with the steps to build the dictionaries.
TARG = words
ARGS = -O
$(TARG): *.ad[bs]
gnatmake $(TARG) $(ARGS)
all: $(TARG)
gnatmake makedict $(ARGS)
gnatmake makeinfl $(ARGS)
gnatmake makestem $(ARGS)
gnatmake makeefil $(ARGS)
#echo Please make the dicitionary
#echo ./makedict DICTLINE.GEN
#echo ./makestem STEMLIST.GEN
#echo ./makeefil EWDSLIST.GEN
#echo ./makeinfl INFLECTS.GEN
debug:
gnatmake -g $(TARG)
clean:
rm -f *.o *.ali b~* core
cleaner: clean
rm -f *.s makedict makeinfl makestem makeefil
cleanest: cleaner
rm -f $(TARG)
Addendum: One approach is to use gcc 4.4.3 on Ubuntu 10.04 with the updated Makefile above. For convenience, I used VirtualBox to host the linux instance.
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Here's a quick test using the title of my second favorite passage from Catulli Carmina.
$ ./words odi et amo
odi V 6 1 PRES ACTIVE IMP 2 S
odeo, odire, odivi(ii), - V TRANS [EXXCW] Later
od.i V 4 1 PRES ACTIVE IMP 2 S
odio, odire, odivi, - V (4th) TRANS [FXXCF] Medieval
hate; dislike; be disinclined/reluctant/adverse to; (usu. PREFDEF);
odi N 2 4 GEN S N Early
odium, odi(i) N (2nd) N [XXXAO]
hate/hatred/dislike/antipathy; odium, unpopularity; boredom/impatience;
hatred (manifested by/towards group), hostility; object of hate/odium;
od.i V 3 1 PERF ACTIVE IND 1 S
odi, odisse, osus V (3rd) PERFDEF [XXXBX]
hate (PERF form, PRES force), dislike; be disinclined/reluctant/adverse to;
et CONJ
et CONJ [XXXAX]
and, and even; also, even; (et ... et = both ... and);
am.o V 1 1 PRES ACTIVE IND 1 S
amo, amare, amavi, amatus V (1st) [XXXAO]
love, like; fall in love with; be fond of; have a tendency to;
Addendum: Once you've got it running, the problem of modifying it remains. A grep for Put_Line\( shows 629 hits; most are in line_stuff and list*. That's where I'd start. As you are learning Ada, there are several good tutorials here.
As much as I like Ada and would encourage you to learn the minimal amount it would require to hack it the way you want...
Really, you are asking for a simple data filter, which it would be quite easy to accomplish by piping your output to awk. If you are running on any flavor of Linux you have awk already (and really should learn to use it). If you are on Windows, you can get awk and all sorts of other useful goodies from MinGW, which is one of the places you'd need to go to get an Ada compiler anyway.
If you do want a Windows Ada compiler, I'd suggest getting GNAT/GCC from there. The two other flavors available, GNAT/GPL and GNAT/PRO are available from AdaCore (the maintainers). However, GNAT/PRO must be purchased and GNAT/GPL renders distributions of any program compiled using it GPL. You might not mind the GPL applying to your program I suppose, but I'm guessing this isn't a serious enough need to spring for commercial support.
If you are on Linux, the GNAT Ada compiler should be available with GCC as an option (if not installed by default). The same two other options from AdaCore are available there too of course, if you like.
Well, you asked about learning Ada. Really, if you are familiar with other compiled procedural languages (eg: C/C++, Java, Pascal, Modula-2, etc.) you shouldn't have too much trouble picking it up. This question covers Ada books. For myself, I generally just use the official LRM as a reference. Unlike most languages, Ada has an internationally standardized Language Reference Manual that is available online for free. It is also quite readable, as such things go.
About compiling: you can use GNAT. It supports Ada83, Ada95, and Ada05. To tell it to use Ada95, use the -gnat95 switch.
You can get it on http://libre.adacore.com/
Can somebody suggest me any disassembler for Atmel AVR 8-bit microcontrollers? There are opensource projects for this?
Thanx.
You can also use avr-objdump, a tool part of the avr-gcc toolset ( http://www.nongnu.org/avr-libc/ ). Ex:
avr-objdump -s -m <avr architecture> .d program.hex > program.dump
where <avr architecture> is found on http://www.nongnu.org/avr-libc/user-manual/using_tools.html
[plug]IDA Pro supports AVR disassembly[/plug]:
As for opensource, AVR GCC package includes a port of objdump, including disassembling functionality.
http://www.onlinedisassembler.com/odaweb/
Lots of platforms (AVR also) but Microchip (which you didn't need either) is missing.
Big plus is that it is web based.
Checkout vAVRdisasm.
AVRDisassembler is an open source (MIT) AVR / Arduino disassembler written in .NET Core (which means it can run on Windows, Mac, Linux). Apart from writing the disassembly to stdout, it can also emit a JSON dump (for interopability, analysis purposes).
Disclaimer: I am the author of said library.
I'm using avrdisas by Johannes Bauer. It works with dumped flash, rather than the .hex file or ELF.
Compiling the following :
.include "tn13def.inc"
ldi r16,1
out ddrb,r16 ; PB0 as output
sbiw r24,1 ; slight wait
brne PC-1
sbi pinb,pinb0 ; toggle
rjmp PC-3 ; forever
produces listing:
C:000000 e001 ldi r16,1
C:000001 bb07 out ddrb,r16 ; PB0 as output
C:000002 9701 sbiw r24,1 ; slight wait
C:000003 f7f1 brne PC-1
C:000004 9ab0 sbi pinb,pinb0 ; toggle
C:000005 cffc rjmp PC-3 ; forever
extracting the flash contents with:
$ avrdude -p t13 -P usb -c usbtiny -U flash:r:flash.bin:r
gives: e001 bb07 9701 f7f1 9ab0 cffc
disassembly:
$ ./avrdisas -a1 -o1 -s1 flash.bin
; Disassembly of flash.bin (avr-gcc style)
.text
main:
0: 01 e0 ldi r16, 0x01 ; 1
2: 07 bb out 0x17, r16 ; 23
; Referenced from offset 0x06 by brne
; Referenced from offset 0x0a by rjmp
Label1:
4: 01 97 sbiw r24, 0x01 ; 1
6: f1 f7 brne Label1
8: b0 9a sbi 0x16, 0 ; 0x01 = 1
a: fc cf rjmp Label1
and this works for me, even if the endian-ness does not match the listing and I would need to resolve 0x17 back to DDRB etc.
As opensource disassembler I've tried Radare2 which is command-line oriented but you can also use the GUI called Cutter. https://rada.re/n/
Or you can just use the classical avr-objdump:
avr-objdump.exe -j .sec1 -d -m avr5 dumpfile.hex
Information source here
The question is rather about disassembling the HEX file and as a solution there are mentioned quite a lot tools above in other answers. Hard to add something more.
But if someone is looking for: it is also possible to disassemble the C/C++ while running in IDE. With Atmel studio with its integrated disassembling tool it can be done following way:
Run project (it can be run in simulator without debugger hardware);
Pause or stop at breakpoint;
Press CTRL + ALT + D
This can be useful in order to verify that particular code fragments are compiled as needed because the optimization sometimes skips/mangles the sequence and leads to some unexpected behavior.