Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

It would be illogical to kill without reason. -- Spock, "Journey to Babel", stardate 3842.4


devel / comp.os.cpm / De-obfuscated Oscar Toledo's 8080 emulator

SubjectAuthor
* De-obfuscated Oscar Toledo's 8080 emulatorEd Batalha
`- Re: De-obfuscated Oscar Toledo's 8080 emulatorLawrence Woodman

1
De-obfuscated Oscar Toledo's 8080 emulator

<trufdh$3slov$2@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=4029&group=comp.os.cpm#4029

  copy link   Newsgroups: comp.os.cpm
Path: i2pn2.org!i2pn.org!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: edbata...@yahoo.com (Ed Batalha)
Newsgroups: comp.os.cpm
Subject: De-obfuscated Oscar Toledo's 8080 emulator
Date: Tue, 7 Feb 2023 21:21:53 +0000
Organization: A noiseless patient Spider
Lines: 583
Message-ID: <trufdh$3slov$2@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 7 Feb 2023 21:21:53 -0000 (UTC)
Injection-Info: reader01.eternal-september.org; posting-host="16989c2d99def3d28debd5d1b9fca64b";
logging-data="4085535"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/b9MyltfpYmYQAYBRVLUI2"
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:51.0) Gecko/20100101 Firefox/51.0
SeaMonkey/2.48
Cancel-Lock: sha1:Vnwc9gXL4DTKUyy+GNT5/dupJJw=
X-Mozilla-News-Host: snews://news.eternal-september.org:563
 by: Ed Batalha - Tue, 7 Feb 2023 21:21 UTC

Hi all,

I have de-obfuscated Oscar Toledo's emulator [1].

I started out by running the C pre-processor to expand the '#defines'
then adjusting some formatting.

The whole emulator runs inside a 'for' loop. The initialisation inside
the 'for' opens all the files and loads the 64Kbytes of memory from file C.
The halt instruction (hlt, 0x76), 118) stops the emulator when
encountered so it is used in the 'for' loop exit condition.
The bulk of the work is done in the 3rd clause of the for loop.

We see a succession of ...?...?...?...?... ... ...:...:...:...:...
K&R 2nd edition has this to say about the ? operator:
"
expr1 ? expr2 : expr3
the expression expr1 is evaluated first. If it is non-zero (true), then
the expression expr2 is evaluated, and it is the value of the
conditional expression. Otherwise expr3 is evaluated, and that is the
value Only one of expr2 and expr3 is evaluated.
"

The way Oscar Toledo did it is: if the 8080 instruction he got from the
memory array makes 'expr1' evaluate to zero then the program flows sends
it to evaluate 'expr3'.
Once I realised that, I started matching the first '?' to the last ':'
and writing those clue comments "/*001*/" up and down the file and
continued from there until I had all of them done. Next was the
formatting related to all those commas. To help me identify which 8080
opcode was being done I looked at a 8080 manual where one of the pages
is a summary of all of them. Lots of decimal to binary to hex
conversions later and I had all opcodes identified.
As I went along I also added comments.

After all that, one comes to the conclusion that the emulator is really
simple and easy to understand and just really nice to study.

Some of the things I really like:
- all in one file
- small variable names
- no unnecessary functions and function calls

[1] https://nanochess.org/emulator.html

(note: my newsgroup client wraps lines at 72 columns. Some editing may
be required if you want to use the code below.)

#include <stdio.h>

unsigned char o[10],l[78114],*c=l,*k=l+64506; // 0xFBFA
e,V,v,u,x,y,z,Z;

main(r,U)char**U;
{

for(
v =fopen(((u =fopen(((e =fopen(((r-2?0:(V
=fopen((1[U]),"rb+")),"C")),"rb+")
,system("stty raw -echo min 0")
,fread(l,78114,1,e)
,fclose((e)),
"B")),"rb+"),"A")),"rb+")
// At the end of initialisation
// v file pointer to file A
// u file pointer to file B
// V file pointer to file in the command line
// array l contains contents of File C (why 78114?)
; 118-(x=*c++) // 0x76 stop instruction, exits for loop
// the x variable contains the current 8080 opcode being
evaluated
// the c variable is the current program counter
/*
o[0] = B register o[1] = C register
o[2] = D register o[3] = E register
o[4] = H register o[5] = L register
o[6] = Flags o[7] = A or accumulator
O[8] = SP high byte o[9] = SP low byte

DB 00 Reads key pressed status
DB 01 Reads key
DB 02 Reads byte from file (Carry=EOF)
D3 xx Writes byte from acc. to console
ED ED 02 Reads sector (128 bytes)
ED ED 03 Writes sector (128 bytes)
*/

;
/*001*/ (y=x/8%8,z=(x&199)-4 )? // 4 INR increment register
// y=0 -> B
// y=1 -> C
// y=2 -> D
// y=3 -> E
// y=4 -> H
// y=5 -> L
// y=6 -> MEMORY POINTED BY HL
// y=7 -> A

/*002*/ (z-= 1 )? // 5 DCR decrement register pair

/*003*/ (z-= 1 )? // 6 MVI move immediate

/*004*/ (z-= 186 )? // 192 RETURN ON FLAG FAMILY
// y=0 -> RNZ
// y=1 -> RZ
// y=2 -> RNC
// y=3 -> RC
// y=4 -> RPO
// y=5 -> RPE
// y=6 -> RP
// y=7 -> RM

/*005*/ (z-= 2 )? // 194 JUMP ON FLAG FAMILY
// y=0 -> RNZ
// y=1 -> RZ
// y=2 -> RNC
// y=3 -> RC
// y=4 -> RPO
// y=5 -> RPE
// y=6 -> RP
// y=7 -> RM

/*006*/ (z-= 2 )? // 196 CALL ON FLAG FAMILY
// y=0 -> RNZ
// y=1 -> RZ
// y=2 -> RNC
// y=3 -> RC
// y=4 -> RPO
// y=5 -> RPE
// y=6 -> RP
// y=7 -> RM

/*007*/ (z-= 3 )? // 199 RST Restart
// y=0 -> JUMP TO ADDR 0
// y=1 -> JUMP TO ADDR 8
// y=2 -> JUMP TO ADDR 16
// y=3 -> JUMP TO ADDR 24
// y=4 -> JUMP TO ADDR 32
// y=5 -> JUMP TO ADDR 40
// y=6 -> JUMP TO ADDR 48
// y=7 -> JUMP TO ADDR 56

/*008*/ (z-= 0,r=(y>5)*2+y,z=(x&207)-1 )? // 1 LXI load register pair
immediate
// y=0 -> BC
// y=2 -> DE
// y=4 -> HL
// y=6 -> SP

/*009*/ (z-= 2 )? // 3 INX increment register pair
// y=0 -> BC
// y=2 -> DE
// y=4 -> HL
// y=6 -> SP

/*010*/ (z-= 6 )? // 9 DAD add register pair to HL
// y=1 -> BC
// y=3 -> DE
// y=5 -> HL
// y=7 -> SP

/*011*/ (z-= 2 )? // 11 DCX increment register pair
// y=0 -> BC
// y=2 -> DE
// y=4 -> HL
// y=6 -> SP

/*012*/ (z-= 182 )? // 193 POP register pair from STACK
// y=0 -> BC
// y=2 -> DE
// y=4 -> HL
// y=6 -> A and Flags

/*013*/ (z-= 4)? // 197 PUSH register pair to STACK
// y=0 -> BC
// y=2 -> DE
// y=4 -> HL
// y=6 -> A and Flags

/*014*/ x/8!=16+0&198+0*8!=x? // 128 ADD r add register to A or 198
ADI add immediate to A
/*015*/ x/8!=16+1&198+1*8!=x? // 136 ADC r add register to A with
carry 206 ACI add immediate to A with carry
/*016*/ x/8!=16+2&198+2*8!=x? // 144 SUB r subtract register 214 SUI
subract immediate from A
/*017*/ x/8!=16+3&198+3*8!=x? // 152 SBB r subtract register with
borrow 222 SUB subract immediate from A with borrow
/*018*/ x/8!=16+4&198+4*8!=x? // 160 ANA r and register with A 230 ANI
and immediate with A
/*019*/ x/8!=16+5&198+5*8!=x? // 168 XRA r exclusive or register with
A 238 XRI exclusive or immediate with A
/*020*/ x/8!=16+6&198+6*8!=x? // 176 ORA r or register with A 246 ORI
or immediate with A
/*021*/ x/8!=16+7&198+7*8!=x? // 184 CMP r compare register with A 254
CPI compare immediate with A

/*022*/ (z=x-2 )? // 2 STAX B store A indirect
/*023*/ (z-= 5 )? // 7 RLC rotate A left
/*024*/ (z-= 3 )? // 10 LDAX B load A indirect
/*025*/ (z-= 5 )? // 15 RRC rotate A right
/*026*/ (z-= 3 )? // 18 STAX D store A indirect
/*027*/ (z-= 5 )? // 23 RAL rotate A left through carry
/*028*/ (z-= 3 )? // 26 LDAX D load A indirect
/*029*/ (z-= 5 )? // 31 RAR rotate A right through carry
/*030*/ (z-= 3 )? // 34 SHLD store H and L direct
/*031*/ (z-= 5 )? // 39 DAA decimal adjust A
/*032*/ (z-= 3 )? // 42 LHLD load H and L direct
/*033*/ (z-= 5 )? // 47 CMA complement A
/*034*/ (z-= 3 )? // 50 STA store A direct
/*035*/ (z-= 5 )? // 55 STC set carry
/*036*/ (z-= 3 )? // 58 LDA load A direct
/*037*/ (z-= 5 )? // 63 CMC complement carry
/*038*/ (z-= 3 +129 )? // 195 JMP jump unconditional
/*039*/ (z-= 6 )? // 201 RET return
/*040*/ (z-= 4 )? // 205 CALL Call unconditional
/*041*/ (z-= 6 )? // 211 0xD3 OUT Output
/*042*/ (z-= 8 )? // 219 0xDB IN Input
/*043*/ (z-= 8 )? // 227 XTHL exchange top of stack with HL
/*044*/ (z-= 6 )? // 233 PCHL HL to program counter
/*045*/ (z-= 2 )? // 235 XCHG exchange HL with DE
/*046*/ (z-= 2 )? // 237 0xED - read or write sectors to disk
/*047*/ (z-= 12)? // 249 SPHL HL to stack pointer
/*048*/ x/64-1? // 64 MOV r1,r2 MOV M,r MOV r,M
/*NO */ ((0 )):
/*048*/ (( // 64 MOV r1,r2 MOV M,r MOV r,M
*((7&y)-6?&o[y&7]:&l[o[5]+256*o[5
-1]])=*((7&x)-6?&o[x&7]:&l[o[5]+256*o[5 -1]])
)):
/*047*/ (( // 249 SPHL HL to stack pointer
9[o]=*((7&5)-6?&o[5&7]:&l[o[5]+256*o[5 -1]])
,8[o]=*((7&4)-6?&o[4&7]:&l[o[5]+256*o[5 -1]])
)):
/*046*/ (( // 237 0xED - read or write sectors to disk
237==*c++? // 2nd also 0xED? Skip it
((int (*)())(2-*c++?fwrite:fread)) //if 3rd byte is 2
read, otherwise write
(l+*k+1[k]*256,128,1,(fseek(y=5[k]-1?u:v // 0=A:, 1=B:
,((3[k]|4[k]<<8)<<7|2[k])<<7
,*((7&7)-6?&o[7&7]:&l[o[5]+256*o[5
-1]])=0)
,y
)
)
:0
)):
// 0[k] = FBFA - Low source/target address
// 1[k] = FBFB - High source/target
address
// 2[k] = FBFC - Sector (0-127)
// 3[k] = FBFD - Cylinder (low byte)
// 4[k] = FBFE - Cylinder (high byte)
// 5[k] = FBFF - Drive (1/2)


Click here to read the complete article
Re: De-obfuscated Oscar Toledo's 8080 emulator

<41a2d1d7-b669-4b4c-bb89-1c06bac87744n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=4032&group=comp.os.cpm#4032

  copy link   Newsgroups: comp.os.cpm
X-Received: by 2002:ac8:5a48:0:b0:3ba:1a25:f52 with SMTP id o8-20020ac85a48000000b003ba1a250f52mr1055066qta.114.1675848233146;
Wed, 08 Feb 2023 01:23:53 -0800 (PST)
X-Received: by 2002:a05:6870:a11e:b0:166:cd98:5b0b with SMTP id
m30-20020a056870a11e00b00166cd985b0bmr192855oae.141.1675848232671; Wed, 08
Feb 2023 01:23:52 -0800 (PST)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.os.cpm
Date: Wed, 8 Feb 2023 01:23:52 -0800 (PST)
In-Reply-To: <trufdh$3slov$2@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=212.159.72.217; posting-account=6IOL2QoAAADcrW98uD49gn028RamCDkC
NNTP-Posting-Host: 212.159.72.217
References: <trufdh$3slov$2@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <41a2d1d7-b669-4b4c-bb89-1c06bac87744n@googlegroups.com>
Subject: Re: De-obfuscated Oscar Toledo's 8080 emulator
From: lorrywoo...@gmail.com (Lawrence Woodman)
Injection-Date: Wed, 08 Feb 2023 09:23:53 +0000
Content-Type: text/plain; charset="UTF-8"
X-Received-Bytes: 2165
 by: Lawrence Woodman - Wed, 8 Feb 2023 09:23 UTC

On Tuesday, 7 February 2023 at 21:21:55 UTC, Ed Batalha wrote:
> I have de-obfuscated Oscar Toledo's emulator [1].
>
> I started out by running the C pre-processor to expand the '#defines'
> then adjusting some formatting.
>
> The whole emulator runs inside a 'for' loop. The initialisation inside
> the 'for' opens all the files and loads the 64Kbytes of memory from file C.
> The halt instruction (hlt, 0x76), 118) stops the emulator when
> encountered so it is used in the 'for' loop exit condition.
> The bulk of the work is done in the 3rd clause of the for loop.

> [SNIP]

Great work. I had a quick go at compiling it but have run out of time
to get it to compile - fixing the wordwrap got a bit complicated for the
time I had.

Nevertheless, with the aid of your notes it was interesting to work
through. I've got a thing for small emulators and indeed am working
on a PDP-8 emulator at the moment.

Best wishes

Lorry

---
XCCP: A Shell Extension for CP/M
https://techtinkering.com/articles/xccp-a-shell-extension-for-cpm/

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor