PureBasic Forum
http://forums.purebasic.com/english/

Hi-quality CPU Tuning of electronic bit reference
http://forums.purebasic.com/english/viewtopic.php?f=12&t=71695
Page 1 of 1

Author:  oryaaaaa [ Fri Nov 09, 2018 1:41 am ]
Post subject:  Hi-quality CPU Tuning of electronic bit reference

Hello, I am creating and distributing ultra-luxurious sound quality sound players.
I checked for INTEL CPU.
This greatly improves the operation reliability of the program code.
Improve image quality, improve sound quality, improve fonts, ultra low noise digital output ...
Thanks.

Sample executable demo "Photoviewer - left up right down - exit enter" Size 124KB
x64 for Windows 8.1 / 10 ( bottom of web page )
http://www.mics.ne.jp/~coolverse/

Code:
; Hi-quality CPU Tuning of electronic bit reference
; Copyright (c) Hiroyuki Yokota (oryaaaaa) in Japan

; run this code
; Please select pb source code
; Exit your program
; ReAsm
; Compile to #BuildName
; display log

#BuildName = "build.exe"

; As you can see, there was an effect even if listed first. Please try it on Mac or Linux.
!JMP PureBasicForumTips_PreLoadJmpAddress
!JMP PureBasicStart
!JMP PB_NewList
!JMP PB_AddElement
!JMP PB_CloseFile
!JMP PB_CreateFile
!JMP PB_Delay
!JMP PB_DeleteFile
!JMP PB_Eof
!JMP PB_FileSize
!JMP PB_FindString
!JMP PB_FlushFileBuffers
!JMP PB_FreeFiles
!JMP PB_FreeFileSystem
!JMP PB_FreeList
!JMP PB_FreeMemorys
!JMP PB_FreeObjects
!JMP PB_GetFilePart
!JMP PB_GetPathPart
!JMP PB_InitFile
!JMP PB_InitList
!JMP PB_InitMemory
!JMP PB_InitProcess
!JMP PB_InitRequester
!JMP PB_Left
!JMP PB_ListSize
!JMP PB_MessageRequester
!JMP PB_MessageRequester2
!JMP PB_NextElement
!JMP PB_OpenFileRequester
!JMP PB_ReadFile
!JMP PB_ReadString
!JMP PB_RemoveString
!JMP PB_ResetList
!JMP PB_Right
!JMP PB_RunProgram3
!JMP PB_WriteStringN
!JMP ExitProcess
!JMP GetModuleHandleW
!JMP HeapCreate
!JMP HeapDestroy
!JMP memset
!JMP SYS_CopyString
!JMP SYS_StringEqual
!JMP SYS_AllocateString4
!JMP SYS_FastAllocateStringFree4
!JMP PB_StringBase
!JMP SYS_InitString
!JMP SYS_FreeStrings
!PureBasicForumTips_PreLoadJmpAddress:

Macro Nop_bxEbxEcxR8d10d_axEaxEdxR9dR11d
  AddElement(Buffer()) : Buffer() = "NOP bx"
  AddElement(Buffer()) : Buffer() = "NOP Ebx"
  AddElement(Buffer()) : Buffer() = "NOP cx"
  AddElement(Buffer()) : Buffer() = "NOP Ecx"
  AddElement(Buffer()) : Buffer() = "NOP bp"
  AddElement(Buffer()) : Buffer() = "NOP Ebp"
  AddElement(Buffer()) : Buffer() = "NOP di"
  AddElement(Buffer()) : Buffer() = "NOP Edi"
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    AddElement(Buffer()) : Buffer() = "NOP R8w"
    AddElement(Buffer()) : Buffer() = "NOP R8d"
    AddElement(Buffer()) : Buffer() = "NOP R10w"
    AddElement(Buffer()) : Buffer() = "NOP R10d"
    AddElement(Buffer()) : Buffer() = "NOP R12w"
    AddElement(Buffer()) : Buffer() = "NOP R12d"
    AddElement(Buffer()) : Buffer() = "NOP R14w"
    AddElement(Buffer()) : Buffer() = "NOP R14d"
  CompilerEndIf
  AddElement(Buffer()) : Buffer() = "NOP ax"
  AddElement(Buffer()) : Buffer() = "NOP Eax"
  AddElement(Buffer()) : Buffer() = "NOP dx"
  AddElement(Buffer()) : Buffer() = "NOP Edx"
  AddElement(Buffer()) : Buffer() = "NOP sp"
  AddElement(Buffer()) : Buffer() = "NOP Esp"
  AddElement(Buffer()) : Buffer() = "NOP si"
  AddElement(Buffer()) : Buffer() = "NOP Esi"
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    AddElement(Buffer()) : Buffer() = "NOP R9w"
    AddElement(Buffer()) : Buffer() = "NOP R9d"
    AddElement(Buffer()) : Buffer() = "NOP R11w"
    AddElement(Buffer()) : Buffer() = "NOP R11d"
    AddElement(Buffer()) : Buffer() = "NOP R13w"
    AddElement(Buffer()) : Buffer() = "NOP R13d"
    AddElement(Buffer()) : Buffer() = "NOP R15w"
    AddElement(Buffer()) : Buffer() = "NOP R15d"
  CompilerEndIf
EndMacro

Macro Xchg_bxEbxEcxR8d10d_axEaxEdxR9dR11d
  AddElement(Buffer()) : Buffer() = "XCHG bh, bl"
  AddElement(Buffer()) : Buffer() = "XCHG bl, bh"
  AddElement(Buffer()) : Buffer() = "XCHG Ebx, Ebx"
  AddElement(Buffer()) : Buffer() = "XCHG ch, cl"
  AddElement(Buffer()) : Buffer() = "XCHG cl, ch"
  AddElement(Buffer()) : Buffer() = "XCHG Ecx, Ecx"
  AddElement(Buffer()) : Buffer() = "XCHG bp, bp"
  AddElement(Buffer()) : Buffer() = "XCHG Ebp, Ebp"
  AddElement(Buffer()) : Buffer() = "XCHG di, di"
  AddElement(Buffer()) : Buffer() = "XCHG Edi, Edi"
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    AddElement(Buffer()) : Buffer() = "XCHG R8w, R8w"
    AddElement(Buffer()) : Buffer() = "XCHG R8d, R8d"
    AddElement(Buffer()) : Buffer() = "XCHG R10w, R10w"
    AddElement(Buffer()) : Buffer() = "XCHG R10d, R10d"
    AddElement(Buffer()) : Buffer() = "XCHG R12w, R12w"
    AddElement(Buffer()) : Buffer() = "XCHG R12d, R12d"
    AddElement(Buffer()) : Buffer() = "XCHG R14w, R14w"
    AddElement(Buffer()) : Buffer() = "XCHG R14d, R14d"
  CompilerEndIf
  AddElement(Buffer()) : Buffer() = "XCHG ah, al"
  AddElement(Buffer()) : Buffer() = "XCHG al, ah"
  AddElement(Buffer()) : Buffer() = "XCHG Eax, Eax"
  AddElement(Buffer()) : Buffer() = "XCHG dh, dl"
  AddElement(Buffer()) : Buffer() = "XCHG dl, dh"
  AddElement(Buffer()) : Buffer() = "XCHG Edx, Edx"
  AddElement(Buffer()) : Buffer() = "XCHG sp, sp"
  AddElement(Buffer()) : Buffer() = "XCHG Esp, Esp"
  AddElement(Buffer()) : Buffer() = "XCHG si, si"
  AddElement(Buffer()) : Buffer() = "XCHG Esi, Esi"
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    AddElement(Buffer()) : Buffer() = "XCHG R9w, R9w"
    AddElement(Buffer()) : Buffer() = "XCHG R9d, R9d"
    AddElement(Buffer()) : Buffer() = "XCHG R11w, R11w"
    AddElement(Buffer()) : Buffer() = "XCHG R11d, R11d"
    AddElement(Buffer()) : Buffer() = "XCHG R13w, R13w"
    AddElement(Buffer()) : Buffer() = "XCHG R13d, R13d"
    AddElement(Buffer()) : Buffer() = "XCHG R15w, R15w"
    AddElement(Buffer()) : Buffer() = "XCHG R15d, R15d"
  CompilerEndIf
EndMacro

Global NewList Buffer.s()
Global NewList InstructionName.s()
Global filename.s, fileno.i, nameaddress.s, compilelog.s
filename= OpenFileRequester("Source PB", "*.pb", "*.pb|*.pb", 0)

If Not FileSize(filename)>0
  End
EndIf

Select MessageRequester("Check source PB file", GetFilePart(filename), #PB_MessageRequester_YesNo)
  Case #PB_MessageRequester_No
    End
EndSelect

DeleteFile(GetPathPart(filename)+"PureBasic.asm")
If filename And FileSize(filename)>0
  RunProgram(#PB_Compiler_Home+"\Compilers\pbcompiler", Chr(34)+filename+Chr(34)+" /MMX /UNICODE /commented", GetPathPart(filename), #PB_Program_Wait)
  filename = GetPathPart(filename) + "PureBasic.asm"
  ;   If Compiler
  ;     While ProgramRunning(Compiler) : Wend   
  ;     CloseProgram(Compiler) ; Close the connection to the program
  ;   EndIf
Else
  MessageRequester("Error!", "There was an error creating the assembly code file.")
EndIf

Delay(3000)
fileno = ReadFile(#PB_Any, filename)
If fileno
  While Eof(fileno)=0
    AddElement(Buffer())
    Buffer() = ReadString(fileno)
  Wend
  CloseFile(fileno)
EndIf

ForEach Buffer()
  If FindString(Buffer(), "extrn ")
    AddElement(InstructionName())
    InstructionName() = RemoveString(Buffer(), "extrn ")
  EndIf
  If ListSize(InstructionName())>1
    If Left(Buffer(), 1)=";"
      Break
    EndIf
  EndIf 
Next
ForEach Buffer()
  If Left(Buffer(), 10) = "_Procedure" And Right(Buffer(), 1)=":"
    AddElement(InstructionName())
    InstructionName() = RemoveString(Buffer(), ":")   
  EndIf
Next

nameaddress = "PureBasicForumTips_PreLoadJmpAddress"+Str(Random(300))
ForEach Buffer()
  If FindString(Buffer(), "PureBasicStart:")
    ; Start Hi-quality CPU Tuning of electronic bit reference
    Nop_bxEbxEcxR8d10d_axEaxEdxR9dR11d
    Nop_bxEbxEcxR8d10d_axEaxEdxR9dR11d
    Xchg_bxEbxEcxR8d10d_axEaxEdxR9dR11d
    Xchg_bxEbxEcxR8d10d_axEaxEdxR9dR11d
    AddElement(Buffer()) : Buffer() = "JMP "+nameaddress
    AddElement(Buffer()) : Buffer() = "JMP PureBasicStart"
    ForEach InstructionName()
      AddElement(Buffer()) : Buffer() = "JMP "+InstructionName()
    Next
    AddElement(Buffer()) : Buffer() = nameaddress+":"
    ; End Hi-quality CPU Tuning of electronic bit reference
    Break
  EndIf
Next

fileno = CreateFile(#PB_Any, filename)
If fileno
  ForEach Buffer()
    WriteStringN(fileno, Buffer())
  Next
  FlushFileBuffers(fileno)
  CloseFile(fileno)
  Delay(3000)
  If FileSize(filename)>0
    Compiler = RunProgram(#PB_Compiler_Home+"\Compilers\pbcompiler", Chr(34)+filename+Chr(34)+" /MMX /UNICODE /REASM /EXE "+Chr(34)+GetPathPart(filename)+#BuildName+Chr(34), GetPathPart(filename), #PB_Program_Open | #PB_Program_Read)
    If Compiler
      While ProgramRunning(Compiler)
        If AvailableProgramOutput(Compiler)
          compilelog + ReadProgramString(Compiler) + Chr(13)
        EndIf
      Wend
      compilelog + Chr(13) + Chr(13)
      compilelog + "Exitcode: " + Str(ProgramExitCode(Compiler))   
      CloseProgram(Compiler) ; Close the connection to the program
      MessageRequester("Compiler log", compilelog)
      MessageRequester("Finished", GetPathPart(filename)+#BuildName)
    EndIf
  EndIf
EndIf

End

Author:  NicTheQuick [ Fri Nov 09, 2018 10:21 am ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

What are you're talking about? Can someone translate this for me?

Author:  oryaaaaa [ Fri Nov 09, 2018 9:13 pm ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

After majoring in electronic engineering, if you are not a researcher who
graduated from the MIT level graduate school, you can not understand
the grounds even if you explain the grounds.
It is very difficult to understand CPU from the electronics point of view.

Author:  NicTheQuick [ Fri Nov 09, 2018 9:36 pm ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

You are funny. :lol:
Quote:
Improve image quality, improve sound quality, improve fonts, ultra low noise digital output ...

All of these things are digital. There are 0s and 1s. You can not improve their quality in any way through some silly code changes. Your monitor displays the image, your soundcard uses digital-to-analog converters to create an analog sound (in all other cases your Bluetooth or USB headsets does this, or sometimes your sound system), improving fonts and their rendering is dependent from your operating system because your PB code uses its libraries and I don't even want to talk about "ultra low noise digital output". That's a really nice joke. :mrgreen:

Author:  oryaaaaa [ Fri Nov 09, 2018 10:07 pm ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

This ultra-low jitter digital solution is a code made for an audio system of about 80,000 dollars or more.

REAL Digital level
D+ 70% up 0.7V - 1.0V
D- 30% down 0.0V -0.3V
GND -0.5V-+0.5V

Display Digital to Analog DA output ... effected
Sound Digital to Analog DA output ... effected
but
Digital to Digital ... no effect ... your opinion (NicTheQuick)

Author:  Sicro [ Sat Nov 10, 2018 1:24 am ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

Quote:
Improve image quality, improve sound quality, improve fonts, ultra low noise digital output ...
Can you describe in more detail what improvements your code is making, please?

I know that the command "NOP" (no operation) slows down the CPU extremely minimally, but this effect is probably so extremely small that a human (e.g. in audio playback) does not notice any difference.
Also, I think that your code is specifically designed for one CPU type only and is not applicable to all Intel CPUs, e.g. because of different CPU speeds (less or more sequences of the "NOP" command are necessary or something else).

Author:  Little John [ Sat Nov 10, 2018 9:40 am ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

oryaaaaa wrote:
This ultra-low jitter digital solution is a code made for an audio system of about 80,000 dollars or more.

Where is the trick or tip for me and other forum members? For using your code, do we have to buy an audio system of about 80,000 dollars or more first?

Author:  DarkDragon [ Sat Nov 10, 2018 6:45 pm ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

Hmm... I did not execute it, but from my understanding, what this code does is, it inserts multi byte nop operations, then xchg operations, and then it creates a code which is not actually being executed, but jumps to every external and internal symbol found?

This could definitely work in some overly complicated way. E.g. the prefetcher could be influenced by this kind of code. Also the alignment of the whole code changes. However, this is rather random and application specific. Also highly depending on the CPU and will not work on all Intel CPUs. Most prefetchers go the YES-way, not the NO-way. So this
Code:
JMP PureBasicForumTips_PreLoadJmpAddress
[...]
JMP _ProcedureWhatever
(All the jumps)
[...]
PureBasicForumTips_PreLoadJmpAddress:

Should look more like a negated jump (I haven't written x86 assembly for some years, so excuse me if the commands are used in a wrong way, but I hope the intention is clear):
Code:
MOV eax, 0
MOV ebx, 1
CMP eax, ebx
JNE PureBasicForumTips_PreLoadJmpAddress
[...]
JMP _ProcedureWhatever
(All the jumps)
[...]
PureBasicForumTips_PreLoadJmpAddress:
However, this should be done right before performance critical code, not right at the beginning, since the prefetcher is very limited. Still, very randomly and application and processor specific, this could optimize the performance.

You can also take a look at the likely/unlikely statements used in some C/C++ codes:
https://kernelnewbies.org/FAQ/LikelyUnlikely

oryaaaaa wrote:
After majoring in electronic engineering, if you are not a researcher who
graduated from the MIT level graduate school, you can not understand
the grounds even if you explain the grounds.
It is very difficult to understand CPU from the electronics point of view.
I don't want to do bashing, but have you ever seen MIT lectures? They are usually not that advanced compared to other universities in other countries.

[Update]
It does not have much effect on the electronic signals, unless you run the code in real time, since the scheduler will randomly switch programs. But the performance could possibly be better or worse, as it changes alignments and cache contents.

Author:  oryaaaaa [ Sat Dec 08, 2018 2:02 am ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

Difficult! Muzukasi-, I can't explaine this technique.
but my ultra-hi-quaility sound player use this technique then ONE (= maybe 1st quality).

Procedure xxxx

ProcedureReturn
(*) EndProcedure

(*)
Nop
Xchg
RET
JMP PureBasicStart
Xchg

I don't understand this code. but improved Sound-Quality.

Code:
; Copyright (c) Hiroyuki Yokota (oryaaaaa)

Macro Nop_bxEbxEcxR8d10d_axEaxEdxR9dR11d
  AddElement(Buffer()) : Buffer() = "NOP bx"
  AddElement(Buffer()) : Buffer() = "NOP Ebx"
  AddElement(Buffer()) : Buffer() = "NOP cx"
  AddElement(Buffer()) : Buffer() = "NOP Ecx"
  AddElement(Buffer()) : Buffer() = "NOP bp"
  AddElement(Buffer()) : Buffer() = "NOP Ebp"
  AddElement(Buffer()) : Buffer() = "NOP di"
  AddElement(Buffer()) : Buffer() = "NOP Edi"
  AddElement(Buffer()) : Buffer() = "NOP R8w"
  AddElement(Buffer()) : Buffer() = "NOP R8d"
  AddElement(Buffer()) : Buffer() = "NOP R10w"
  AddElement(Buffer()) : Buffer() = "NOP R10d"
  AddElement(Buffer()) : Buffer() = "NOP R12w"
  AddElement(Buffer()) : Buffer() = "NOP R12d"
  AddElement(Buffer()) : Buffer() = "NOP R14w"
  AddElement(Buffer()) : Buffer() = "NOP R14d"
  AddElement(Buffer()) : Buffer() = "NOP ax"
  AddElement(Buffer()) : Buffer() = "NOP Eax"
  AddElement(Buffer()) : Buffer() = "NOP dx"
  AddElement(Buffer()) : Buffer() = "NOP Edx"
  AddElement(Buffer()) : Buffer() = "NOP sp"
  AddElement(Buffer()) : Buffer() = "NOP Esp"
  AddElement(Buffer()) : Buffer() = "NOP si"
  AddElement(Buffer()) : Buffer() = "NOP Esi"
  AddElement(Buffer()) : Buffer() = "NOP R9w"
  AddElement(Buffer()) : Buffer() = "NOP R9d"
  AddElement(Buffer()) : Buffer() = "NOP R11w"
  AddElement(Buffer()) : Buffer() = "NOP R11d"
  AddElement(Buffer()) : Buffer() = "NOP R13w"
  AddElement(Buffer()) : Buffer() = "NOP R13d"
  AddElement(Buffer()) : Buffer() = "NOP R15w"
  AddElement(Buffer()) : Buffer() = "NOP R15d"
EndMacro

Macro Xchg_bxEbxEcxR8d10d_axEaxEdxR9dR11d
  AddElement(Buffer()) : Buffer() = "XCHG bh, bl"
  AddElement(Buffer()) : Buffer() = "XCHG bl, bh"
  AddElement(Buffer()) : Buffer() = "XCHG Ebx, Ebx"
  AddElement(Buffer()) : Buffer() = "XCHG ch, cl"
  AddElement(Buffer()) : Buffer() = "XCHG cl, ch"
  AddElement(Buffer()) : Buffer() = "XCHG Ecx, Ecx"
  AddElement(Buffer()) : Buffer() = "XCHG bp, bp"
  AddElement(Buffer()) : Buffer() = "XCHG Ebp, Ebp"
  AddElement(Buffer()) : Buffer() = "XCHG di, di"
  AddElement(Buffer()) : Buffer() = "XCHG Edi, Edi"
  AddElement(Buffer()) : Buffer() = "XCHG R8w, R8w"
  AddElement(Buffer()) : Buffer() = "XCHG R8d, R8d"
  AddElement(Buffer()) : Buffer() = "XCHG R10w, R10w"
  AddElement(Buffer()) : Buffer() = "XCHG R10d, R10d"
  AddElement(Buffer()) : Buffer() = "XCHG R12w, R12w"
  AddElement(Buffer()) : Buffer() = "XCHG R12d, R12d"
  AddElement(Buffer()) : Buffer() = "XCHG R14w, R14w"
  AddElement(Buffer()) : Buffer() = "XCHG R14d, R14d"
  AddElement(Buffer()) : Buffer() = "XCHG ah, al"
  AddElement(Buffer()) : Buffer() = "XCHG al, ah"
  AddElement(Buffer()) : Buffer() = "XCHG Eax, Eax"
  AddElement(Buffer()) : Buffer() = "XCHG dh, dl"
  AddElement(Buffer()) : Buffer() = "XCHG dl, dh"
  AddElement(Buffer()) : Buffer() = "XCHG Edx, Edx"
  AddElement(Buffer()) : Buffer() = "XCHG sp, sp"
  AddElement(Buffer()) : Buffer() = "XCHG Esp, Esp"
  AddElement(Buffer()) : Buffer() = "XCHG si, si"
  AddElement(Buffer()) : Buffer() = "XCHG Esi, Esi"
  AddElement(Buffer()) : Buffer() = "XCHG R9w, R9w"
  AddElement(Buffer()) : Buffer() = "XCHG R9d, R9d"
  AddElement(Buffer()) : Buffer() = "XCHG R11w, R11w"
  AddElement(Buffer()) : Buffer() = "XCHG R11d, R11d"
  AddElement(Buffer()) : Buffer() = "XCHG R13w, R13w"
  AddElement(Buffer()) : Buffer() = "XCHG R13d, R13d"
  AddElement(Buffer()) : Buffer() = "XCHG R15w, R15w"
  AddElement(Buffer()) : Buffer() = "XCHG R15d, R15d"
EndMacro

ForEach Buffer()
  If Left(Buffer(), 5) = "  RET"
    PreviousElement(Buffer())
    Nop_bxEbxEcxR8d10d_axEaxEdxR9dR11d
    Xchg_bxEbxEcxR8d10d_axEaxEdxR9dR11d
    NextElement(Buffer())
    AddElement(Buffer()) : Buffer() = "JMP PureBasicStart"
    Xchg_bxEbxEcxR8d10d_axEaxEdxR9dR11d
  EndIf
Next

ForEach Buffer()
  If FindString(Buffer(), "; Procedure")
    If Not FindString(Buffer(), "; ProcedureReturn") ; [10.20] Bug head Nontallion x64 AVX2 SSE41
      Nop_bxEbxEcxR8d10d_axEaxEdxR9dR11d
      Xchg_bxEbxEcxR8d10d_axEaxEdxR9dR11d
    EndIf
  EndIf 
Next


Nop .. No operation (Stop CPU circut)
Xchg ... Stabilizer (Idling CPU circut)

PINK HQ , Bug head , Nontallion , Sound player for hi-end systems.
Nop Nop ...run .... Bad sound quality and ... broke Mother board and any parts
Xchg Xchg ...run .... No power sound quality
Nop Xchg ...run ..... Best sound quality and beautiful screen quality

If you change PureBasic.asm like this, the screen display will be beautiful as well.

Thank you.

Author:  DontTalkToMe [ Sat Dec 08, 2018 1:32 pm ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

oryaaaaa wrote:
If you change PureBasic.asm like this, the screen display will be beautiful as well.


Also your program will smell nice.

Author:  Kiffi [ Sat Dec 08, 2018 2:06 pm ]
Post subject:  Re: Hi-quality CPU Tuning of electronic bit reference

DontTalkToMe wrote:
oryaaaaa wrote:
If you change PureBasic.asm like this, the screen display will be beautiful as well.
Also your program will smell nice.

:lol:

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/