flat assembler
Message board for the users of flat assembler.

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

Author
Thread Post new topic Reply to topic
codestar



Joined: 25 Dec 2014
Posts: 254
codestar 23 Feb 2015, 22:36
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: 16143 Time(s)

miracle.gif


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

miracle4.gif


Description: Templates to design instructions (*.PUB)
Download
Filename: encode.zip
Filesize: 22.08 KB
Downloaded: 896 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
codestar 24 Feb 2015, 04:41
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: 20630
Location: In your JS exploiting you and your system
revolution 24 Feb 2015, 06:02
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
codestar 24 Feb 2015, 06:36
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: 767
tthsqe 24 Feb 2015, 13:20
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
codestar 25 Feb 2015, 17:07
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
codestar 28 Feb 2015, 03:30
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: 117
Location: Argentina
pabloreda 28 Feb 2015, 13:56
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
codestar 28 Feb 2015, 17:13
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: 117
Location: Argentina
pabloreda 28 Feb 2015, 18:30
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
codestar 28 Feb 2015, 18:36
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
codestar 28 Feb 2015, 18:36
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: 117
Location: Argentina
pabloreda 28 Feb 2015, 19:01
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 © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.