flat assembler
Message board for the users of flat assembler.

Index > Assembly > New version of TetrOS

Author
Thread Post new topic Reply to topic
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7404
Location: Kraków, Poland
Tomasz Grysztar
While preparing to organize a 512-byte coding contest for the 20th anniversary of fasm, I decided to revisit my own old piece. Obviously, as an organizer I'm not going to participate in the new contest myself, but perhaps an example from me could serve as an inspiration for potential contestants.

TetrOS is a boot sector game I wrote in 2004 for a 512-byte OS contest we had at the time. It did not attempt to be anything more than a game, but I thought that the fact that it is bootable (plus the pun in the name) should be enough for it to qualify. I did submit it in a bit of a hurry, though, and it was a bit unpolished - as I admitted in the comment to my submission.

It did not win any notable place in the actual contest, but is had been appreciated nonetheless. Some kind soul has even given it a page on MobyGames with nice little description and several screenshots.

It is worth noting that many of game design choices, like the width of well (12 columns instead of standard 10), were made to replicate the feel of my personal favorite, a Tetris built into DOS Navigator (which I used to play for hours to clear my mind while coding in the DOS days). The main reason why I defined all the pieces directly through data (instead of attempting to generate them with some trick) was that I wanted all of them to behave the same as I was used to. A feature that did not make the cut was the scoring system - Tetris in DOS Navigator gave you more points for clearing the lines higher in the well, and that encouraged more risky play patterns. I liked that approach, but then I decided to remove it from TetrOS before submission, because I thought that it might appear random at first and give impression of something that had to be done because of the space constraints (while it was in fact the opposite of that).

Now, as I went back to this old code and started cleaning it up, I found out that in many places it could be optimized better, some of the instructions were in fact completely redundant. I realized I may be able to reclaim enough space to fit some additional features. So I did my best and I managed to add what felt like the most missing one - a preview of the forthcoming block.

And here it comes, a shiny new version:
Code:
; TetrOS version 1.02
; by Tomasz Grysztar

; Requires VGA and 80386 CPU or higher.
; Version 1.01 was submitted in 2004 for a 512-byte OS contest.

; For your playing pleasure, it's a boot-sector Tetris game.
; Keys:
;   Left - move left
;   Right - move right
;   Up - rotate
;   Down - drop
;   Esc - new game at any time

format binary as 'img'
org 7C00h

ROWS = 23
COLUMNS = 12
DELAY = 4

virtual at 46Ch
  clock dw ?
end virtual

virtual at bp
  current dw ?
  current_column db ?
  current_row dw ?
  next dw ?
  score dw ?
  last_tick dw ?
  random dw ?
end virtual

label well at 9000h
label pics at well-2*64

        xor     ax,ax
        mov     sp,8000h
        mov     ss,ax
        mov     ds,ax
        mov     es,ax
        push    ax
        push    start
        retf

start:
        mov     bp,sp

        mov     al,13h
        int     10h

        mov     di,3*4
        mov     ax,int_3
        stosw
        xor     ax,ax
        stosw
        lea     di,[next]
        stosw   ; [next]
        stosw   ; [score]
        mov     ax,[clock]
        stosw   ; [last_tick]
        stosw   ; [random]

        mov     di,pics
        mov     cx,64
        mov     al,1    ; remove this instruction to get randomized background
        rep     stosb
        mov     ah,15
        mov     dx,7
      @@:
        mov     al,15
        stosb
        mov     al,ah
        mov     cl,6
        rep     stosb
        mov     ax,0708h
        stosb
        dec     dx
        jnz     @b
        mov     cl,8
        rep     stosb

        or      ax,-1
        stosw
        stosw
        stosw
        mov     cl,ROWS+4
        mov     ax,11b + (-1) shl (COLUMNS+2)
        rep     stosw
new_piece:
        mov     bx,[random]
        mov     ax,257
        mul     bx
        inc     ax
        mov     cx,43243
        div     cx
        mov     [random],dx
        and     bx,7
        jz      new_piece
        shl     bx,1
        mov     ax,[pieces+bx-2]
        xchg    ax,[next]
        or      ax,ax
        jz      new_piece
        lea     di,[current]
        stosw   ; [current]
        mov     al,COLUMNS/2
        stosb   ; [current_column]
        mov     ax,well + (3+ROWS-4)*2
        stosw   ; [current_row]
        mov     si,no_move
        call    first_move
        jz      update_screen
        inc     bp      ; game over

process_key:
        xor     ah,ah
        int     16h
        mov     al,ah
        dec     ah
        jz      start
        test    bp,bp
        jnp     process_key
        mov     si,rotate
        cmp     al,48h
        je      action
        mov     si,left
        cmp     al,4Bh
        je      action
        mov     si,right
        cmp     al,4Dh
        je      action
        cmp     al,50h
        jne     main_loop

drop_down:
        call    do_move_down
        jz      drop_down

action:
        call    do_move

update_screen:
        mov     bx,7
        mov     dx,12h
        mov     ah,2
        int     10h
        mov     cl,12
      print_score:
        mov     ax,[score]
        shr     ax,cl
        and     al,0Fh
        cmp     al,10
        sbb     al,69h
        das
        mov     ah,0Eh
        int     10h
        sub     cl,4
        jnc     print_score
        push    es
        push    0A000h
        pop     es
        mov     si,well+3*2
        mov     di,320*184+160-(COLUMNS*8)/2
      draw_well:
        lodsw
        push    si
        mov     dl,COLUMNS
        xchg    bx,ax
        shr     bx,2
        call    draw_row
        pop     si
        cmp     si,well+(3+ROWS)*2
        jb      draw_well
        mov     di,320*100+250
        mov     bx,[next]
      draw_preview:
        mov     dl,4
        call    draw_row
        cmp     di,320*68
        ja      draw_preview
        pop     es

main_loop:
        mov     ah,1
        int     16h
        jnz     process_key
        mov     ax,[clock]
        sub     ax,[last_tick]
        cmp     al,DELAY
        jb      main_loop
        add     [last_tick],ax
        call    do_move_down
        jz      update_screen
        mov     dx,1
        mov     si,well+3*2
        mov     di,si
      check_row:
        lodsw
        inc     ax
        jz      remove_row
        dec     ax
        stosw
        jmp     check_next_row
      remove_row:
        shl     dx,1
      check_next_row:
        cmp     di,well+(3+ROWS)*2
        jb      check_row
        add     [score],dx
        jmp     new_piece

draw_row:
        push    di
      blit_row:
        shr     bx,1
        mov     si,pics
        jnc     blit_block
        add     si,64
      blit_block:
        mov     cx,8
        rep     movsb
        add     di,320-8
        test    si,111111b
        jnz     blit_block
        sub     di,320*8-8
        dec     dx
        jnz     blit_row
        pop     di
        sub     di,320*8
        ret

do_move_down:
        mov     si,down
do_move:
        mov     ax,clear_piece
        int3
first_move:
        push    dword [current]
        call    si
        xor     ch,ch
        mov     ax,test_piece
        int3
        mov     al,draw_piece and 0FFh
        pop     edx
        or      ch,ch
        jz      @f
        mov     dword [current],edx
      @@:
        int3
      no_move:
        ret
down:
        sub     byte [current_row],2
        ret
left:
        dec     [current_column]
        ret
right:
        inc     [current_column]
        ret
rotate:
        mov     cx,3
     @@:
        bt      [current],cx
        rcl     dx,1
        add     cl,4
        cmp     cl,16
        jb      @b
        sub     cl,17
        jnc     @b
        mov     [current],dx
        ret

int_3:
        mov     di,[current_row]
        mov     bx,4
      on_piece_row:
        mov     dx,[current]
        mov     cl,bh
        shr     dx,cl
        and     dx,1111b
        mov     cl,[current_column]
        add     cl,4
        shl     edx,cl
        shr     edx,4
        call    ax
        add     bh,4
        scasw
        dec     bl
        jnz     on_piece_row
        iret

clear_piece:
        not     dx
        and     [di],dx
        ret
test_piece:
        test    [di],dx
        jz      @f
        inc     ch
     @@:
        ret
draw_piece:
        or      [di],dx
        ret

pieces dw 0010001000100010b
       dw 0010011000100000b
       dw 0010001001100000b
       dw 0100010001100000b
       dw 0000011001100000b
       dw 0100011000100000b
       dw 0010011001000000b

rb 7C00h+510-$
dw 0AA55h    
The code has been tested in DOSBox and on an actual hardware (my Pentium 60 machine from 1995).

You may notice a comment that encourages to remove one of the instructions - this change makes the background color be chosen randomly every time the game is restarted. It is fun, but also some of the color combinations look horrible (a perk of the randomness), so I decided to not enable this by default and keep the original look, even though this change also makes the code even smaller.

One of the tricks in TetrOS is to hook the interrupt 3 to make a function callable with just a single byte (INT3 instruction). Converting the function to an interrupt also makes it automatically preserve flags - which is actually relevant here and allows to save on PUSHF/POPF that would be otherwise needed. Nonetheless, in the new version the INT3 function is only called three times and the trick no longer gains anything. It breaks even, though, so I decided to keep it - as I consider it a kind of a trademark of TetrOS that I should not remove without a really good reason.

Because I deemed the addition of a piece preview the most important one, I did not manage to bring back the height-dependent scoring system this time. Perhaps this is something I may still work towards in the future.


Description: TetrOS 1.02 in action
Filesize: 1.97 KB
Viewed: 683 Time(s)

TetrOS.png


Description: TetrOS 1.02 - source code and bootable image (please scroll down the thread to find later revisions)
Download
Filename: tetros102.zip
Filesize: 2.35 KB
Downloaded: 18 Time(s)

Post 03 Nov 2019, 17:49
View user's profile Send private message Visit poster's website Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 237
Location: the-ideom
Mike Gonta
Tomasz Grysztar wrote:
While preparing to organize a 512-byte coding contest for the 20th anniversary of fasm, ...
It seems quite fitting (in an historical context) that such a contest (that is dependent on the BIOS)* coincides with Intel saying "Bye to BIOS" by 2020.


*Of course, there is always emulation, which is the sincerest form of flattery.

_________________
Mike Gonta
the-ideom - now you know how to compile

https://mikegonta.com
Post 04 Nov 2019, 09:11
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7404
Location: Kraków, Poland
Tomasz Grysztar
Mike Gonta wrote:
It seems quite fitting (in an historical context) that such a contest (that is dependent on the BIOS)* coincides with Intel saying "Bye to BIOS" by 2020.
I did not plan to limit the contest this way (see the thread where we discuss potential rules), but perhaps this is a good reason to make it so.

Back to the new TetrOS: I made another kind of screenshot, this is my old DOS PC running it. Note that it's a variant that has instruction responsible for background color commented out to enable random coloring.


Description: TetrOS 1.02 (altered) on a CRT monitor
Filesize: 125.43 KB
Viewed: 599 Time(s)

TetrOS_CRT.jpg


Post 04 Nov 2019, 11:49
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7404
Location: Kraków, Poland
Tomasz Grysztar
Another previously overlooked (and substantial) optimization allowed me to implement a height-dependent scoring system that I wanted. Please welcome version 1.03:
Code:
; TetrOS version 1.03
; by Tomasz Grysztar

; Requires VGA and 80386 CPU or higher.
; Version 1.01 was submitted in 2004 for a 512-byte OS contest.

; For your playing pleasure, it's a boot-sector Tetris game.
; Keys:
;   Left - move left
;   Right - move right
;   Up - rotate
;   Down - drop
;   Esc - new game at any time

format binary as 'img'
org 7C00h

ROWS = 23
COLUMNS = 12
DELAY = 4

virtual at 46Ch
  clock dw ?
end virtual

virtual at bp
  current dw ?
  current_column db ?
  current_row dw ?
  next dw ?
  score dw ?
  last_tick dw ?
  random dw ?
end virtual

label well at 9000h
label pics at well-2*64

        xor     ax,ax
        mov     sp,8000h
        mov     ss,ax
        mov     ds,ax
        mov     es,ax
        push    ax
        push    start
        retf

start:
        mov     bp,sp

        mov     al,13h
        int     10h

        mov     di,3*4
        mov     ax,int_3
        stosw
        xor     ax,ax
        stosw
        lea     di,[next]
        stosw   ; [next]
        stosw   ; [score]
        mov     ax,[clock]
        stosw   ; [last_tick]
        stosw   ; [random]

        mov     di,pics
        mov     cx,64
        mov     al,1    ; remove this instruction to get randomized background
        rep     stosb
        mov     ah,15
        mov     dx,7
      @@:
        mov     al,15
        stosb
        mov     al,ah
        mov     cl,6
        rep     stosb
        mov     ax,0708h
        stosb
        dec     dx
        jnz     @b
        mov     cl,8
        rep     stosb

        or      ax,-1
        stosw
        stosw
        stosw
        mov     cl,ROWS+4
        mov     ax,not ( (1 shl COLUMNS - 1) shl ((16-COLUMNS)/2) )
        rep     stosw
new_piece:
        mov     bx,[random]
        mov     ax,257
        mul     bx
        inc     ax
        mov     cx,43243
        div     cx
        mov     [random],dx
        and     bx,7
        jz      new_piece
        shl     bx,1
        mov     ax,[pieces+bx-2]
        xchg    ax,[next]
        or      ax,ax
        jz      new_piece
        lea     di,[current]
        stosw   ; [current]
        mov     al,6
        stosb   ; [current_column]
        mov     ax,well + (3+ROWS-4)*2
        stosw   ; [current_row]
        mov     si,no_move
        call    first_move
        jz      update_screen
        inc     bp      ; game over

process_key:
        xor     ah,ah
        int     16h
        mov     al,ah
        dec     ah
        jz      start
        test    bp,bp
        jnp     process_key
        mov     si,rotate
        cmp     al,48h
        je      action
        mov     si,left
        cmp     al,4Bh
        je      action
        mov     si,right
        cmp     al,4Dh
        je      action
        cmp     al,50h
        jne     main_loop

drop_down:
        call    do_move_down
        jz      drop_down

action:
        call    do_move

update_screen:
        mov     bx,7
        mov     dx,12h
        mov     ah,2
        int     10h
        mov     cl,12
      print_score:
        mov     ax,[score]
        shr     ax,cl
        and     al,0Fh
        cmp     al,10
        sbb     al,69h
        das
        mov     ah,0Eh
        int     10h
        sub     cl,4
        jnc     print_score
        push    es
        push    0A000h
        pop     es
        mov     si,well+3*2
        mov     di,320*184+160-(COLUMNS*8)/2
      draw_well:
        lodsw
        push    si
        mov     dl,COLUMNS
        xchg    bx,ax
        shr     bx,(16-COLUMNS)/2
        call    draw_row
        pop     si
        cmp     si,well+(3+ROWS)*2
        jb      draw_well
        mov     di,320*100+250
        mov     bx,[next]
      draw_preview:
        mov     dl,4
        call    draw_row
        cmp     di,320*68
        ja      draw_preview
        pop     es

main_loop:
        mov     ah,1
        int     16h
        jnz     process_key
        mov     ax,[clock]
        sub     ax,[last_tick]
        cmp     al,DELAY
        jb      main_loop
        add     [last_tick],ax
        call    do_move_down
        jz      update_screen
        movzx   dx,byte [current_row]
        shr     dx,2
        mov     si,well+3*2
        mov     di,si
      check_row:
        lodsw
        inc     ax
        jz      remove_row
        dec     ax
        stosw
        jmp     check_next_row
      remove_row:
        shl     dx,1
      check_next_row:
        cmp     di,well+(3+ROWS)*2
        jb      check_row
        add     [score],dx
        jmp     new_piece

draw_row:
        push    di
      blit_row:
        shr     bx,1
        mov     si,pics
        jnc     blit_block
        add     si,64
      blit_block:
        mov     cx,8
        rep     movsb
        add     di,320-8
        test    si,111111b
        jnz     blit_block
        sub     di,320*8-8
        dec     dx
        jnz     blit_row
        pop     di
        sub     di,320*8
        ret

do_move_down:
        mov     si,down
do_move:
        mov     al,1
        int3
first_move:
        push    dword [current]
        call    si
        xor     ax,ax
        int3
        inc     ax
        pop     edx
        test    ah,ah
        jz      @f
        mov     dword [current],edx
      @@:
        int3
      no_move:
        ret
down:
        sub     byte [current_row],2
        ret
left:
        dec     [current_column]
        ret
right:
        inc     [current_column]
        ret
rotate:
        mov     cx,3
     @@:
        bt      [current],cx
        rcl     dx,1
        add     cl,4
        cmp     cl,16
        jb      @b
        sub     cl,17
        jnc     @b
        mov     [current],dx
        ret

int_3:
        mov     di,[current_row]
        mov     bx,4
      on_piece_row:
        mov     dx,[current]
        mov     cl,bh
        shr     dx,cl
        and     dx,1111b
        mov     cl,[current_column]
        add     cl,4
        shl     edx,cl
        shr     edx,4
        test    al,al
        jz      @f
        xor     [di],dx
      @@:
        test    [di],dx
        jz      @f
        inc     ah
      @@:
        add     bh,4
        scasw
        dec     bl
        jnz     on_piece_row
        iret

pieces dw 0010001000100010b
       dw 0010011000100000b
       dw 0010001001100000b
       dw 0100010001100000b
       dw 0000011001100000b
       dw 0100011000100000b
       dw 0010011001000000b

rb 7C00h+510-$
dw 0AA55h    
It still has 6 spare bytes. So to put them to good use, I tried one more thing: semi-levels marked by increasing falling speed. The increments happen every 100h points and every 400h revert back to the starting speed for a bit of respite. This time I enabled the background randomization:
Code:
; TetrOS version 1.04
; by Tomasz Grysztar

; Requires VGA and 80386 CPU or higher.
; Version 1.01 was submitted in 2004 for a 512-byte OS contest.

; For your playing pleasure, it's a boot-sector Tetris game.
; Keys:
;   Left - move left
;   Right - move right
;   Up - rotate
;   Down - drop
;   Esc - new game at any time

format binary as 'img'
org 7C00h

ROWS = 23
COLUMNS = 12
BACKGROUND = 0 ; background color, 0 for randomized

virtual at 46Ch
  clock dw ?
end virtual

virtual at bp
  current dw ?
  current_column db ?
  current_row dw ?
  next dw ?
  score dw ?
  last_tick dw ?
  random dw ?
end virtual

label well at 9000h
label pics at well-2*64

        xor     ax,ax
        mov     sp,8000h
        mov     ss,ax
        mov     ds,ax
        mov     es,ax
        push    ax
        push    start
        retf

start:
        mov     bp,sp

        mov     al,13h
        int     10h

        mov     di,3*4
        mov     ax,int_3
        stosw
        xor     ax,ax
        stosw
        lea     di,[next]
        stosw   ; [next]
        stosw   ; [score]
        mov     ax,[clock]
        stosw   ; [last_tick]
        stosw   ; [random]

        mov     di,pics
        mov     cx,64
if BACKGROUND
        mov     ax,0F00h + BACKGROUND
else
        mov     ah,15
end if
        rep     stosb
        mov     dx,7
      @@:
        mov     al,15
        stosb
        mov     al,ah
        mov     cl,6
        rep     stosb
        mov     ax,0708h
        stosb
        dec     dx
        jnz     @b
        mov     cl,8
        rep     stosb

        or      ax,-1
        stosw
        stosw
        stosw
        mov     cl,ROWS+4
        mov     ax,not ( (1 shl COLUMNS - 1) shl ((16-COLUMNS)/2) )
        rep     stosw
new_piece:
        mov     bx,[random]
        mov     ax,257
        mul     bx
        inc     ax
        mov     cx,43243
        div     cx
        mov     [random],dx
        and     bx,7
        jz      new_piece
        shl     bx,1
        mov     ax,[pieces+bx-2]
        xchg    ax,[next]
        or      ax,ax
        jz      new_piece
        lea     di,[current]
        stosw   ; [current]
        mov     al,6
        stosb   ; [current_column]
        mov     ax,well+(3+ROWS-4)*2
        stosw   ; [current_row]
        mov     si,no_move
        call    first_move
        jz      update_screen
        inc     bp      ; game over

process_key:
        xor     ah,ah
        int     16h
        mov     al,ah
        dec     ah
        jz      start
        test    bp,bp
        jnp     process_key
        mov     si,rotate
        cmp     al,48h
        je      action
        mov     si,left
        cmp     al,4Bh
        je      action
        mov     si,right
        cmp     al,4Dh
        je      action
        cmp     al,50h
        jne     main_loop

drop_down:
        call    do_move_down
        jz      drop_down

action:
        call    do_move

update_screen:
        mov     bx,7
        mov     dx,12h
        mov     ah,2
        int     10h
        mov     cl,12
      print_score:
        mov     ax,[score]
        shr     ax,cl
        and     al,0Fh
        cmp     al,10
        sbb     al,69h
        das
        mov     ah,0Eh
        int     10h
        sub     cl,4
        jnc     print_score
        push    es
        push    0A000h
        pop     es
        mov     si,well+3*2
        mov     di,320*184+160-(COLUMNS*8)/2
      draw_well:
        lodsw
        push    si
        mov     dl,COLUMNS
        xchg    bx,ax
        shr     bx,(16-COLUMNS)/2
        call    draw_row
        pop     si
        cmp     si,well+(3+ROWS)*2
        jb      draw_well
        mov     di,320*100+250
        mov     bx,[next]
      draw_preview:
        mov     dl,4
        call    draw_row
        cmp     di,320*68
        ja      draw_preview
        pop     es

main_loop:
        mov     ax,01FFh
        int     16h
        jnz     process_key
        xor     al,byte [score+1]
        and     al,11b
        mov     cx,[clock]
        sub     cx,[last_tick]
        cmp     cl,al
        jbe     main_loop
        add     [last_tick],cx
        call    do_move_down
        jz      update_screen
        movzx   dx,byte [current_row]
        shr     dx,2
        mov     si,well+3*2
        mov     di,si
      check_row:
        lodsw
        inc     ax
        jz      remove_row
        dec     ax
        stosw
        jmp     check_next_row
      remove_row:
        shl     dx,1
      check_next_row:
        cmp     di,well+(3+ROWS)*2
        jb      check_row
        add     [score],dx
        jmp     new_piece

draw_row:
        push    di
      blit_row:
        shr     bx,1
        mov     si,pics
        jnc     blit_block
        add     si,64
      blit_block:
        mov     cx,8
        rep     movsb
        add     di,320-8
        test    si,111111b
        jnz     blit_block
        sub     di,320*8-8
        dec     dx
        jnz     blit_row
        pop     di
        sub     di,320*8
        ret

do_move_down:
        mov     si,down
do_move:
        mov     al,1
        int3
first_move:
        push    dword [current]
        call    si
        xor     ax,ax
        int3
        inc     ax
        pop     edx
        test    ah,ah
        jz      @f
        mov     dword [current],edx
      @@:
        int3
      no_move:
        ret
down:
        sub     byte [current_row],2
        ret
left:
        dec     [current_column]
        ret
right:
        inc     [current_column]
        ret
rotate:
        mov     cx,3
     @@:
        bt      [current],cx
        rcl     dx,1
        add     cl,4
        cmp     cl,16
        jb      @b
        sub     cl,17
        jnc     @b
        mov     [current],dx
        ret

int_3:
        mov     di,[current_row]
        mov     bx,4
      on_piece_row:
        mov     dx,[current]
        mov     cl,bh
        shr     dx,cl
        and     dx,1111b
        mov     cl,[current_column]
        add     cl,4
        shl     edx,cl
        shr     edx,4
        test    al,al
        jz      @f
        xor     [di],dx
      @@:
        test    [di],dx
        jz      @f
        inc     ah
      @@:
        add     bh,4
        scasw
        dec     bl
        jnz     on_piece_row
        iret

pieces dw 0010001000100010b
       dw 0010011000100000b
       dw 0010001001100000b
       dw 0100010001100000b
       dw 0000011001100000b
       dw 0100011000100000b
       dw 0010011001000000b

rb 7C00h+510-$
dw 0AA55h    
This is the last revision for now, I promise. After playing it I think that it finally feels like a real game.


Description: TetrOS 1.03 - source code and bootable image
Download
Filename: tetros103.zip
Filesize: 2.34 KB
Downloaded: 10 Time(s)

Description: TetrOS 1.04 - source code and bootable image
Download
Filename: tetros104.zip
Filesize: 2.37 KB
Downloaded: 11 Time(s)

Post 04 Nov 2019, 12:59
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-2019, Tomasz Grysztar.

Powered by rwasa.