flat assembler
Message board for the users of flat assembler.

flat assembler > Examples and Tutorials > Miracle CPU. Micro-Power Machine. ASM+DASM

Author
Thread Post new topic Reply to topic
codestar



Joined: 25 Dec 2014
Posts: 254
Quote:
* All fixed 2-byte instructions. Old style punch-card programming made easy and modern
* 16 registers. A1-A12 are general
* Most efficient CPU encodings, 800%-1200%+ smaller than Intel+ARM
* 12+ addressing modes. Fast pointer arithmetic
* Versatile immediate sizes: 1-8, 10, 12, 16, 20, 24, 28, 32. Use only what's needed
* Access IP/BP/SP/SF (settings, flags)
* IF blocks to create for/while/loop

Download: Miracle Assembler + Disassembler

Disassembly:
Code:
; MIRACLE DISASSEMBLER ; OFFSET_CODE______________ASM____________________________ 00000000 $0602 .code #140 00000002 $D08C $data 00000004 $0000 bug 00000006 $077F sys $0000007F 00000008 $0820 push a1 0000000A $0809 pop a7 0000000C $0CFF push $000000FF 0000000E $0D12 push $12345678 00000010 $D345 $data 00000012 $D678 $data 00000014 $2801 mov a1=a2 00000016 $2829 mov a3=a7 00000018 $277F mov a12=1111111b 0000001A $1ABC mov a1=$00000ABC 0000001C $2C87 mov a1=$07ABC123 0000001E $DABC $data 00000020 $D123 $data 00000022 $3281 mov1 a1=*a2++ 00000024 $3ECA mov4 *a7=*a3++ 00000026 $37D9 mov1 *a9++=*a2++ 00000028 $3D73 mov4 *a12++=a4 0000002A $4A0A mov a1=a2[+a3] 0000002C $5A0A mov a1=a2[+a3*4] 0000002E $641F mov a1=a2[+1111b*4] 00000030 $4E0A mov a1=&a2[+a3] 00000032 $5E0A mov a1=&a2[+a3*4] 00000034 $6C1F mov a1=&a2[+1111b*4] 00000036 $460A mov a1[+a2]=a3 00000038 $5242 mov a1[+a2*4]=a3 0000003A $741F mov a1[+1111b*4]=a2 0000003C $8001 add a1,a2 0000003E $80F7 sub a12,a5 00000040 $9210 shl a1,#16 00000042 $9358 shr a3,#24 00000044 $9468 sar a4,#8 00000046 $8313 and a3,a4 00000048 $8381 or a1,a2 0000004A $980E cmp a1,#14 0000004C $E607 gif e,+$0000005A 0000004E $8D06 ror a1,a2,a3 00000050 $A008 add a1,a3,#1 00000052 $A091 sub a1,ip,#4 00000054 $A012 add a1,ip,$00000ABC 00000056 $DABC $data 00000058 $8481 not a1,a2 0000005A $E487 gif ne,-$0000004C 0000005C $8501 tst a1,a2 0000005E $8581 adc a1,a2 00000060 $8601 sbc a1,a2 00000062 $8681 mul a1,a2 00000064 $9E11 div a1,#17 00000066 $2800 nop 00000068 $E901 if a1=a2 { 0000006A $2800 nop 0000006C $EE1F } 0000006E $EBC1 if a1>a2 { 00000070 $2800 nop 00000072 $EE1F } 00000074 $F010 enter #1,0,0 { 00000076 $6452 mov a1=bp[+0010b*4] 00000078 $A0C0 sub a3,a1,#1 0000007A $3288 mov1 a2=*a1++ 0000007C $8509 tst a2,a2 0000007E $E052 go ne,-$0000007A 00000080 $8082 sub a1,a3 00000082 $F203 leave 00000084 $F1FF } 00000086 $E941 if a1<>a2 { 00000088 $0C00 push $00000000 0000008A $B40B call -$00000074 0000008C $EE1F } ; SIZE: #142 BYTES
INSTRUCTIONS
Code:
; INSTRUCTIONS... ; SYSTEM: 0000.00-0000.011111+ ; 0000.000000000000 - BUG. BREAKPOINT (0) ; 0000.01000XXXXXXX - EXCEPTION ; 0000.01100000SSS? - .SECTION $12?$24 ; 0000.01110####### - SYS #7. INTERRUPT ; 0000.011110000000 - ISR A1=#7, A2=0/&. GET/SET ; 0000.011111------ - <RESERVED> ; PUSH/POP: 0000.100-0000.111+ ; 0000.100000P*AAAA - PUSH/POP *@4 ; 0000.101?######## - PUSH #8?$32 ; 0000.110000*?#### - PUSH *($16?$28) ; 0000.110001PRABCD - PUSHM/POPM A1-A4 ; 0000.110010PRABCD - PUSHM/POPM $16. MULTIPLE ; 0000.11001100NABC - PUSHB 2-3 # 0/1 BITS ; 0000.110100&+#### - PUSH &/BP[+-#4*4] ; 0000.1101010+#### - POP BP[+-#4*4] ; 0000.111--------- - <RESERVED> ; MOVEMENT: 0001-0010.1111, 0011-0111.11+ ; # SECTIONS: <5.4 ; 0001.############ - MOV @0=#12 ; 0010.0AAA######## - MOV @3=#8 ; 0010.100?AAAABBBB - MOV @4=(@4?#4) ; 0010.110?######## - MOV @0=($20?$32) ; 0010.1110*?AA#### - MOV/4 @2=*($16?$28) ; 0010.111100*?AAAA - MOV/4 @4=*($12?$24) ; 0010.11111------- - <RESERVED> ; 0011.%**++AAAABBB - MOV/1%4 *@4++=*@3++ ; 0100.001%*+AAAA?? - MOV/1%4 *@4++=(0,1,-1,$12) ; 0100.01+AAABBBCCC - MOV @3[+-@3]=@3 ; 0100.1&+AAABBBCCC - MOV @3=&@3[+-@3] ; 0101.00+AAABBBCCC - MOV @3[+-@3*4]=@3 ; 0101.1&+AAABBBCCC - MOV @3=&@3[+-@3*4] ; 0110.&+AAABBB#### - MOV @3=&@3[+-#4*4] ; 0111.0+AAABBB#### - MOV @3[+-#4*4]=@3 ; 0111.10+AAA####?? - MOV @3[+-#4*4]=(0,1,-1,$12) ; 0111.11---------- - <RESERVED> ; ARITHMETIC: 1000.0-1010.1+. # SECTIONS: <2.3 ; OLD/CURRENT... ; 1000.0@@@@AAAABBB - ALU4 @4,@3 ; 1000.1@@@AAABBBCC - ALU3 @3,@3,@2 ; 1001.@@@@AAA##### - ALU4 @3,#5 ; 1010.0@@@@AABBB## - ALU4 @2,@3,(1,4,$12,$24) ; 1010.1----------- - <RESERVED> ; 2-DO: NEW DESIGN... ; 1000.0@@@@AAAABBB - ALU4 @4,@3 ; 1000.1@@@@AABBBCC - ALU4 @2,@3,@2 ; 1001.0@@@AAA##### - ALU3 @3,#5 ; 1001.10@@@@AAAA## - ALU4 @4,(1,2,4,8) ; 1001.11@@@AABBB## - ALU3 @2,@3,(1,2,4,8) ; 1010.00@@@@?AABBB - ALU4 @2,@3,($12?$24) ; 1010.01@@@@**AABB - ALU4/4 *@2,*@2 ; 1010.1----------- - <RESERVED> ; TRANSFER: 1011-1100.1+. # SECTIONS: <2 ; 1011.+P########## - GO/CALL IP+-(#10*2) ; 1100.0+P00000AAAA - GO/CALL IP+-(@4*2) ; 1100.1----------- - <RESERVED> ; 1101.$$$$$$$$$$$$ - [$DATA] ; DATA.AAAABBBBCCCC - $DATA $12 ; CONDITIONAL: 1110.00-1110.111+. # SECTIONS: <1 ; 1110.00+?CCCC#### - GO <C>,+-#4?$16 ; 1110.01+CC####### - GO <C2>,+-#7 ; E,NE,LE,GE ; 1110.10+?AAAABBBB - GIF @4<C>@4, +-$8?$20 ; DATA.CCCC######## - $DATA $8?$20 ; 1110.110%+?AAAABB - CMP%1/4 *@4++,(@2?0,1,-1,$12) ; 1110.111--------- - <RESERVED> ; FUNCTION: 1111.000-1111.001+. # SECTIONS: <1 ; 1111.000ZPPPPLLLL - ENTER(NP,LS,ZL?) ; 1111.000111111111 - ENDF ; 1111.0010PPPP00## - LEAVE (0,1,-1,R0|NONE) ; 1111.011--------- - <RESERVED> ; 1111.1----------- - <RESERVED>, CO-PROCESSOR, ; FPU, GPU, MULTI-BYTE ; @@=0-3, @@@=0-7, @@@@=0-15 = ; @@/@@@: ADD SUB CMP SHL SHR SAR ROR AND ; @@@@: OR NOT TST ADC SBC MUL DIV IMUL ; 12+ ADDRESSING MODES: ; *A++=*B++ ; ABP ; *A++=# ; API ; A=B[+-C] ; ABC ; A=B[+-C*4] ; ABCS ; A=B[+-#*4] ; ABIS ; A=&B[+-C] ; AABC ; A=&B[+-C*4] ; AABCS ; A=&B[+-#*4] ; AABIS ; B[+-A]=C ; BAC ; B[+-A*4]=C ; BACS ; B[+-#*4]=C ; BICS ; B[+-#*4]=# ; BISI
Data word usage:
Image


Description: Miracle CPU
Filesize: 42.01 KB
Viewed: 2384 Time(s)

miracle.gif


Description:
Filesize: 34.12 KB
Viewed: 2662 Time(s)

miracle4.gif


Description: Templates to design instructions (*.PUB)
Download
Filename: encode.zip
Filesize: 22.08 KB
Downloaded: 93 Time(s)



Last edited by codestar on 21 Mar 2015, 03:20; edited 1 time in total
Post 23 Feb 2015, 22:36
View user's profile Send private message Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
I posted this Miracle assembler + disassembler in the Examples forum and it was moved here. It is 3K+ lines of unique code that is not related Power-Machine and not a repeat of any code in this thread.
Post 24 Feb 2015, 04:41
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15859
Location: 162173 Ryugu
That was me. It looked very similar so I thought it was appropriate. Anyhow I've moved it back now.
Post 24 Feb 2015, 06:02
View user's profile Send private message Visit poster's website Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
Thanks.

This is a good example of how to create an assembler and/or disassembler with FASM's macro system. To assemble, run EXAMPLE.ASM > .BIN. To disassemble EXAMPLE.BIN to .TXT, run DISASSEMBLE.INC. My next step is to create a translator or emulator.
Post 24 Feb 2015, 06:36
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 714
this looks good.
I was thinking of making an emulator.
Do you have a full specification of the instruction set? Does it do 64 bit? floating point?
Post 24 Feb 2015, 13:20
View user's profile Send private message Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
REGISTERS

A1-A12 are the general registers. All registers are usable with push/pop and mov r=r/i7+. IP+BP are the only registers that get prioritized to @3+ for the addressing modes, parameters, locals, static variables, relative addresses. SP+SF are not accessed the same way.

Image

Typo: Ignore current ASSEMBLE.INC which says SP is low. Failed to update comment.

tthsqe: No, nothing is official yet. Yesterday, I started writing an emulator in C/C++ here (VC6) (move *.BIN into /Release/). It detects all instructions, displays registers and supports push/pop/mov. Next step is to create a "program memory block" (1-8MB? specify) where offset #4 = file.p+4. I'd like to see your attempt at creating an emulator for any CPU. Example: Thumb1 may be easier and is testable, but if you want to use/edit/extend Miracle encodings, be my guest. For information on emulation, check out "Marat Fayzullin".

In the template card (*.PUB), see the first line: "XXX4 @4,@4". Any 16 instructions can be defined in the operation "CODE", be it for "ALU/FPU/GPU" which are just labels to categorize them. CODE: 0-15=fmov, fadd, fmul, etc.
Code:
0000.CODEAAAABBBB ; XXX4 @4,@4
Miracle emulator design/sketch:

Image
Code:
// 0001.############ - MOV @0=#12 inline void _movi12() { registers[0]=(code&0xFFF); } // 0010.0AAAA####### - MOV @4=#7 inline void _movri7() { registers[(code>>7)&0xF]=(code&0x7F); }


Last edited by codestar on 05 Mar 2015, 03:21; edited 1 time in total
Post 25 Feb 2015, 17:07
View user's profile Send private message Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
Miracle CPU Update. Minimal emulator started in /VC6/ (move *.BIN into /Release/). Allocates a "program memory block; rom size" of 512K/$80000 (default) then the *.BIN sets SP to $0074000 (28BIT) for PUSH/POP. Previews:

Assembler:
Code:
macro @mova [p] { common local m, n, % %=%size @mode=0 define m 0 ; 0011.%**++AAAABBB - MOV/1%4 *@4++=*@3++ match =0 \ *a++==*b++, m p \{ ; *A++=*B++ ; ABP d2 (0011b shl 12) or \ (% shl 11) or (1111b shl 7) \ or (a shl 3) or b define m 1 \} match =0 \ *a==*b++, m p \{ d2 (0011b shl 12) or \ (% shl 11) or (1101b shl 7) \ or (a shl 3) or b define m 1 \} match =0 \ a==*b++, m p \{ d2 (0011b shl 12) or \ (% shl 11) or (0101b shl 7) \ or (a shl 3) or b define m 1 \} match =0 \ *a++==*b, m p \{ d2 (0011b shl 12) or \ (% shl 11) or (1110b shl 7) \ or (a shl 3) or b define m 1 \} ; 0100.001%*+AAAA?? - MOV/1%4 *@4++=(0,1,-1,$12) match =0 \ *a++==b, m p \{ if b is.r? d2 (0011b shl 12) or \ (% shl 11) or (1010b shl 7) \ or (a shl 3) or b else n=-1 if b=0 | b=1 n=b else if b=-1 n=2 else verify.i12 b n=3 end if d2 (0100b shl 12) or \ (% shl 8) or (11b shl 6) \ or (a shl 2) or n if n=3 $data b end if end if define m 1 \} ; 0101.1&+AAABBBCCC - MOV @3=&@3[+-@3*4] ; 0110.&+AAABBB#### - MOV @3=&@3[+-#4*4] match =0 \ a==&b[+c*4], m p \{ ; @mov r1=r2[+r3*4] verify.r a, b if c is.r? d2 (0101b shl 12) or \ (111b shl 9) or (a shl 6) \ or (b shl 3) or c else verify.i4 c d2 (0110b shl 12) or \ (11b shl 10) or (a shl 7) \ or (b shl 4) or c end if define m 1 \} match =0 \ a==&b[+c], m p \{ ; 0100.1&+AAABBBCCC - MOV @3=&@3[+-@3] verify.r a, b, c d2 (0100b shl 12) or \ (111b shl 9) or (a shl 6) \ or (b shl 3) or c define m 1 \} ; 0101.1&+AAABBBCCC - MOV @3=&@3[+-@3*4] ; 0110.&+AAABBB#### - MOV @3=&@3[+-#4*4] match =0 \ a==b[+c*4], m p \{ ; @mov r1=r2[+r3*4] verify.r a, b if c is.r? d2 (0101b shl 12) or \ (101b shl 9) or (a shl 6) \ or (b shl 3) or c else verify.i4 c d2 (0110b shl 12) or \ (01b shl 10) or (a shl 7) \ or (b shl 4) or c end if define m 1 \} match =0 \ a==b[+c], m p \{ ; @mov r1=r2[+r3] ; 0100.1&+AAABBBCCC - MOV @3=&@3[+-@3] verify.r a, b, c d2 (0100b shl 12) or \ (101b shl 9) or (a shl 6) \ or (b shl 3) or c define m 1 \} ; 0101.00+AAABBBCCC - MOV @3[+-@3*4]=@3 ; B[+-A*4]=C ; BACS ; B[+-#*4]=C ; BICS ; B[+-#*4]=# ; BISI match =0 \ b[+a*4]==c, m p \{ verify.r b, c if a is.r? ; 0101.00+AAABBBCCC - MOV @3[+-@3*4]=@3 d2 (0101b shl 12) or \ (001b shl 9) or (a shl 6) \ or (b shl 3) or c else if c is.r? ; 0111.0+AAABBB#### - MOV @3[+-#4*4]=@3 d2 (0111b shl 12) or \ (01b shl 10) or (b shl 7) \ or (c shl 4) or a else ; 0111.10+AAA####?? - MOV @3[+-#4*4]=(0,1,-1,$12) 'Unsupported' end if end if define m 1 \} ; B[+-A]=C ; BAC ; 0100.01+AAABBBCCC - MOV @3[+-@3]=@3 match =0 \ b[+a]==c, m p \{ verify.r a, b, c d2 (0100b shl 12) or \ (011b shl 9) or (b shl 6) \ or (a shl 3) or c define m 1 \} if m eq 0 'Error' end if }

Disassembler:
Code:
format binary as 'TXT'
Code:
macro put [x] { db x }
Code:
macro disassemble name { local i, p, n virtual at 0 p:: file name n=$ end virtual define file.size n @ip=0 while @ip<file.size load a byte from p:@ip load b byte from p:@ip+1 @code=((a shl 8) or b) dasm p put RET @ip=@ip+2 end while }
Emulator:
Code:
int main() { source=(byte*) load_program(FILENAME); if (!source) { printf("Error loading file: %s\n", FILENAME); goto e; } run_program(); e: end_program(); getch(); return 0; } int run_program() { run=1; while (run) { printf("%08X ", registers[ip]); if (!fetch_code()) goto e; printf("$%04X ", code); id=detect_code(); if (id==I_NONE) { printf("Error: " \ "Undefined Instruction. "); printf("IP=%08X\n", registers[ip]-2); return 0; } execute_code(); printf("\n"); } e: printf("\n"); return 1; }
Code:
if (i>=PROGRAM_SIZE) { printf("\n\nError: " \ "Invalid Address: $%08X. " \ "IP=$%08X\n", i, registers[ip]-2); return 0; } if (!registers[sp]) { printf("\n\nError: " \ "Stack Not Initialized. " \ "SP=0. IP=$%08X\n", registers[ip]-2); return 0; } if (registers[sp]>=(PROGRAM_SIZE-256)) { printf("\n\nError: " \ "Invalid Stack Address. " \ "SP: $%08X. IP=$%08X\n", registers[sp], registers[ip]-2); return 0; }
Image

IDEA: *.MX: MIRACLE EXECUTABLE
Code:
i16 signature='MX' ; header: 32 bytes... i16 version=0 i32 program.size=512K i32 data.begin, data.size i32 code.begin, code.size i32 media.begin, media.size
Post 28 Feb 2015, 03:30
View user's profile Send private message Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 84
Location: Argentina
you know f18 chip?

http://www.greenarraychips.com/home/documents/index.html

I'm writing a compiler and the mayor drawback is few registers in i86, if you make a virtual chip and then asm to other chips (i86,i64,arm) the key, IMHO is the register asignation, if you use a memory adress for simulate more register, this slow down the code
Post 28 Feb 2015, 13:56
View user's profile Send private message Visit poster's website Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
Quote:
"I'm writing a compiler and the mayor drawback is few registers in i86"
I agree. I32 doesn't provide enough registers to create a good expression parser (f(a[b[c[d[i]/x]/y]/z])). ARM32 and the old M68K (Sega Genesis) have 16 registers. Most minimal compilers use the stack-based method of conversion - takes 2+ registers: mov x | push x | pop y | operate - and that's essentially the same as using "memory registers".

Emulation will never be as fast as native code and translation.

* Script Languages: Slowest and biggest. Interpretation of text, source with comments, whitespace, unknown values. Example: JavaScript
* Virtual Machine: Fast interpretation of pre-compiled binary, but does very little per instruction (add x). No memory access, dependencies, problems. Example: Java
* Virtual CPU, Native Machine: Fastest interpretation. A type of VM that resembles a real CPU; IP, stack, memory access, interrupts, debugger. Best translation, closest to native code. Example: Miracle
Quote:
you know f18 chip?
No, first time I've seen it. After browsing that page for 5-7 minutes (GreenArrays), it has pretty graphics and words, but I don't see any evidence of the claims/theories. Where are the numbers, instructions, statistics, comparisons? (Advertisement like "organic vegetables". No evidence that it's manufactured in a safer natural way).
Code:
mov4 *a1++=*a2++ ; Miracle: 2 bytes ; Intel: 7 bytes? if global memory pointers, add another 8+ bytes or so mov ebx, [ecx] add ecx, 4 mov [eax], ebx add eax, 4
As for FPU, I will support IEEE 754 float+double precision after I finish integer arithmetic. Miracle CPU will not be official until I have a game (Binary Master) working on Android. I prefer Mini-X5 with HDMI over Windows 8.
Post 28 Feb 2015, 17:13
View user's profile Send private message Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 84
Location: Argentina
the organic style is for low power use, in a forth day a student show this chip running with a limon for battery.

the pdf in this page cover all abou how programing in this computer, basic are 5 bits instruction zero operand, in words of 18 bits packet 4 instruction, the last slot is 3 bits, only fit 8 instruction. the actual design have 144 f18 in array.

I'm not use floating point at all, (my last work are in 3d voxel graphics, for example), but yes fixed point.
Post 28 Feb 2015, 18:30
View user's profile Send private message Visit poster's website Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
Quote:
IMHO is the register asignation, if you use a memory adress for simulate more register, this slow down the code
Yes, but I think it's a worthy tradeoff for portability, small size, safety and good runtime debugging with accurate error messages. Often times, I want to "Run Debug" with names/etc (executable.size+3K-5K?) or "Run As Virtual CPU" temporarily to determine the cause of problems then "Run" (standard/"release") once they are corrected. Since emulation takes time anyway, I decided to improve error checking in the beginning. Ultimately, I need the ability to step through individual instructions and watch registers+flags as they change.


Last edited by codestar on 28 Feb 2015, 20:07; edited 1 time in total
Post 28 Feb 2015, 18:36
View user's profile Send private message Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
Quote:
the pdf in this page cover all abou how programing in this computer
Link?
Post 28 Feb 2015, 18:36
View user's profile Send private message Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 84
Location: Argentina
all the pdf in this page
http://www.greenarraychips.com/home/documents/index.html

the images are pdf!!
Post 28 Feb 2015, 19:01
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.