Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unofficial 8085 opcodes are not properly decompiled #2299

Open
marcin-chwedczuk opened this issue Sep 24, 2020 · 2 comments
Open

Unofficial 8085 opcodes are not properly decompiled #2299

marcin-chwedczuk opened this issue Sep 24, 2020 · 2 comments

Comments

@marcin-chwedczuk
Copy link

marcin-chwedczuk commented Sep 24, 2020

Describe the bug
8085 CPU comes with a few undocumented instructions that where found a few years after its introduction. You can find a full list of these unofficial opcodes e.g. in asXXXX assembler documentation.

One of the undocumented instructions that I encountered is ldsi. Ghidra decompiler does not know this instruction and stops binary -> assembly decompilation after encountering it. This is somehow annoying when you try to reverse engineer old code (think retro-computing).

To Reproduce
Try to decompile this file (Intel HEX format):

:2000000021FE3FF9CD270076C307007E6F079F67C9CD1700C82BC97B955F7A9C210100FA51
:200020002400B3C9B337C9C5C5C53B3805D5210080D1D93803D52100A0D1D93801D52100DC
:20004000C0D1D93805EDE5210000D17D123803EDE5210000D17D122101007CB5CA80003843
:2000600001EDE5210F00D17D123805EDE5210F00D17D123803EDE5210F00D17D12C35700C7
:0B008000C38300EB21070039F9EBC936
:00000001FF

It was compiled from two assembly files (file responsible for starting C environment, stripped down to only necesary parts) in as8085 format:

;       Run time start off for Small C.
;        cseg
        .module CSTART
        .area   CSTART (REL,CON) ;program area CRTSO is RELOCATABLE
        .list   (err, loc, bin, eqt, cyc, lin, src, lst, md)
        .nlist  (pag)
        .globl  cstartend
	.globl 	cceq, ccgchar, cccmp

	lxi h,#0x3ffe ; Initialize stack on even address.
		      ; Stack grows downwards.
        sphl

        call    main    ; call main program

stop:
	hlt ; stop processor
	jmp stop

; fetch char from (HL) and sign extend into HL
ccgchar: mov     a,m
ccsxt:  mov     l,a
        rlc
        sbb     a
        mov     h,a
        ret

; DE == HL
cceq:   call    cccmp
        rz
        dcx     h
        ret

; signed compare of DE and HL
;   carry is sign of difference [set => DE < HL]
;   zero is zero/non-zero
cccmp:  mov     a,e
        sub     l
        mov     e,a
        mov     a,d
        sbb     h
        lxi     h,1             ;preset true
        jm      cccmp1
        ora     e               ;resets carry
        ret
cccmp1: ora     e
        stc
        ret
;
cstartend:
       .end

and the example main.asm:

; Small C 8080
;	Coder (2.4,84/11/27)
;	Front End (2.7,84/11/28)
;	Front End for ASXXXX (2.8,13/01/20)

		;program area SMALLC_GENERATED is RELOCATABLE
		.module SMALLC_GENERATED
		.list   (err, loc, bin, eqt, cyc, lin, src, lst, md)
		.nlist  (pag)
		.area  SMALLC_GENERATED  (REL,CON,CSEG)
;#define TRUE (1)
;#define FALSE (0)
;main() {
main:
;	char *outport1, *outport2, *inport;
	push	b
	push	b
	push	b
;	char in;
	dcx 	sp
;	outport1 = 0x8000;
	ldsi	#5
	push	d
	lxi 	h,#32768
	pop 	d
	shlx
;	outport2 = 0xA000;
	ldsi	#3
	push	d
	lxi 	h,#40960
	pop 	d
	shlx
;	inport = 0xC000;
	ldsi	#1
	push	d
	lxi 	h,#49152
	pop 	d
	shlx
;	*outport1 = 0;
	ldsi	#5
	lhlx
	push	h
	lxi 	h,#0
	pop 	d
	mov 	a,l
	stax	d
;	*outport2 = 0;
	ldsi	#3
	lhlx
	push	h
	lxi 	h,#0
	pop 	d
	mov 	a,l
	stax	d
;	while (TRUE) {
$2:
	lxi 	h,#1
	mov 	a,h
	ora 	l
	jz  	$3
;		*inport = 0xF;
	ldsi	#1
	lhlx
	push	h
	lxi 	h,#15
	pop 	d
	mov 	a,l
	stax	d
;		*outport1 = 0xF;
	ldsi	#5
	lhlx
	push	h
	lxi 	h,#15
	pop 	d
	mov 	a,l
	stax	d
;		*outport2 = 0xF;
	ldsi	#3
	lhlx
	push	h
	lxi 	h,#15
	pop 	d
	mov 	a,l
	stax	d
;	}
	jmp 	$2
$3:
;	return;
	jmp 	$1
;}
$1:
	xchg
	lxi 	h,#7
	dad 	sp
	sphl
	xchg
	ret
		.area  SMALLC_GENERATED_DATA  (REL,CON,DSEG)
	.globl	main

;0 error(s) in compilation
;	literal pool:0
;	global pool:1
;	Macro pool:70
	;	.end

The second listing was generated from C using (not fully working right now) SmallC compiler:

#define TRUE (1)
#define FALSE (0)

main() {
	char *outport1, *outport2, *inport;
	char in;

	outport1 = 0x8000;
	outport2 = 0xA000;
	inport = 0xC000;

	*outport1 = 0;
	*outport2 = 0;

	while (TRUE) {
		*inport = 0xF; // its like this for dbg purposes
		*outport1 = 0xF;
		*outport2 = 0xF;
	}

	return;
}

Expected behavior
Unofficial 8085 opcodes should be decompiled. Possibly a new language flavour should be introduced like 8085+unofficial.

Environment (please complete the following information):

  • macOS 10.15.6
  • Java Version: 14.0.1
  • Ghidra Version: 9.1.2
@esaulenka
Copy link
Contributor

@marcin-chwedczuk, can you help with tests of my implementation ?

Now, I faced with two issues:

  • i didnt find detailed description of two new flags
  • sequence ldsi, push, lxi, pop in your sample decodes to strange C code. Problem seems to be somewhere else.

In order to not interfere here, you can write me email (my nick @ gmail.com) or add issue to my github.

@marcin-chwedczuk
Copy link
Author

marcin-chwedczuk commented Oct 5, 2020

@esaulenka Unfortunately I cannot help you right now. If you are willing to wait one or two weeks then I will try to help you as much as I can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants