00:00:00 --- log: started forth/03.07.03 01:10:01 --- join: deluxe (~deluxe@pD9EE1050.dip.t-dialin.net) joined #forth 01:10:37 bonjour 01:15:45 --- quit: kc-movie ("[x]chat") 01:28:09 bye ;-) 01:28:27 --- quit: a7r (Read error: 110 (Connection timed out)) 02:32:11 --- join: Serg_Penguin (Serg_Pengu@212.34.52.140) joined #forth 02:32:16 --- quit: Serg_Penguin (Client Quit) 03:59:42 --- join: mur (murr@baana-62-165-185-218.phnet.fi) joined #forth 04:36:13 --- join: tathi (~josh@pcp02123722pcs.milfrd01.pa.comcast.net) joined #forth 07:03:11 --- join: PoppaVic (~pfv@s39.waters.gtlakes.com) joined #forth 07:39:13 --- part: tathi left #forth 08:16:45 --- join: wossname (wossname@HSE-QuebecCity-ppp81458.qc.sympatico.ca) joined #forth 08:39:48 --- quit: PoppaVic ("(I don't need a reason)") 08:52:16 --- join: deluxe_ (~deluxe@pD9EE121A.dip.t-dialin.net) joined #forth 08:59:05 --- quit: wossname () 09:01:16 --- join: Herkamire (~jason@h0030657bb518.ne.client2.attbi.com) joined #forth 09:10:09 --- quit: deluxe (Read error: 110 (Connection timed out)) 09:18:17 --- part: deluxe_ left #forth 10:14:34 --- join: PoppaVic (~pfv@s195.waters.gtlakes.com) joined #forth 10:19:19 anyone have a moment for a logic-bomb? 10:21:15 *the terminal*:12: Cannot tick compile-only word (try COMP' ... DROP) 10:21:15 ' ['] 10:21:15 ^^^ 10:22:42 weird 10:22:59 well, that's gforth - but the point remains 10:23:25 Isn't tick nothing more than find + nfa>cfa ? 10:23:29 I havn't figured out how I want immediates to work. 10:23:56 I've dropped a user-accessible STATE altogether, and words may now be 4-mode. 10:24:45 But, this doesn't answer the immediate dilemma - which is: isn't tick just lookup & field-recalc? 10:25:48 Herkamire: dcc offering 10:26:50 Seems to me that ' (tick) should ALWAYS work.. But that the compiler and interpreter are the ones that need to check modes and scream as required. 10:33:12 --- join: w1k1_ (~w1k1@pD9EE121A.dip.t-dialin.net) joined #forth 10:36:58 --- part: PoppaVic left #forth 10:41:45 --- part: w1k1_ left #forth 10:43:01 --- join: w1k1 (~w1k1@pD9EE120E.dip.t-dialin.net) joined #forth 10:46:36 --- join: a7r (~a7r@206.72.82.135) joined #forth 10:46:41 hey 11:07:50 --- join: kc5tja (~kc5tja@ip68-8-206-137.sd.sd.cox.net) joined #forth 11:07:50 --- mode: ChanServ set +o kc5tja 11:35:55 hey a7r 11:36:21 wb kc5tja 11:36:22 Herkamire: how's it going? 11:36:23 kc5tja: yoh 11:37:33 where's robert? 11:39:16 I'm ok. I'm feeling lazy, but I'm starting to enjoy procrastinating :) 11:39:49 re 11:40:27 * kc5tja is writing a quick C and assembly language application for Linux which attempts to guage the best method of compiling FS/Forth code to native code. 11:40:45 * kc5tja is going to investigate the use of ESI and EBP to hold the data stack pointer, along with a couple of other things. 11:40:57 how will it guage? 11:41:02 It'll time them. 11:41:10 are you looking to see how gcc optomizes? 11:41:12 The method that takes the least amount of time wins. 11:41:15 No 11:41:23 Though GCC's output is used as a baseline. 11:41:31 Herkamire: how's sifbot btw? ;-) 11:42:04 w1k1: I took sifbot down because it was incomplete, undocumented, and I've lost interest in working on it. 11:42:55 w1k1: you can have the code if you want to play with it. 11:47:05 :-) 11:47:06 --- quit: a7r (Read error: 60 (Operation timed out)) 11:48:00 now I'm playing with PPC asm, pre-parsed source (like aha and enth/flux) and contemplating writing a colorforth editor. 11:48:47 right now I'm mostly thinking about how to implement blocks for my source. 11:49:52 Herkamire: thx, yes i would like to have a look at it :-) 11:50:39 the forth: http://herkamire.homeip.net:5000/svn/sif/ 11:50:46 the bot: http://herkamire.homeip.net:5000/svn/sifbot/ 11:51:42 sometimes I shut this computer down at night. 11:51:59 Herkamire: can't promise you docs for it, but my (newbie) thoughts, questions and answers(hopefully;-) will go into a ForthFAQWiki right away.. 11:52:40 Herkamire: sometimes? lol, same here.. 11:53:42 at least until i have that ultralowpower server.. ;-) 11:53:47 currently I'm running a proxy that get's my girl friend's computer online. Since she usually get's up before me, I'll probably be leaving my computer on a lot. 11:54:12 is the wiki up yet? 11:55:12 I haven't written a wiki sort of thing yet. 11:58:10 OK, GCC baseline code can do it in about 15 seconds without -O3 -fomitframepointer. Lets see what it can do with those optimizations. 11:59:19 Yikes -- 8.3 seconds. :D 11:59:42 Now to hand-assemble the equivalent Forth code. 12:18:00 OK, for all you NASM experts here, how the *HELL* does one make a symbol public? 12:18:06 [extern] works fine, but [public] doesn't. 12:18:42 Ahh, global. 12:27:34 OK, this really sucks... :( 12:27:53 Does Linux allow *any* kind of stack pointer manipulations AT ALL? 12:28:04 I do something like: 12:28:08 mov ebp,esp 12:28:10 sub esp,1024 12:28:20 call Foo <-- it segfaults here; Foo is NOT executed. 12:28:35 It just doesn't make any sense. 12:28:44 Oh, wait...I need to push EBP first. Forgot about that. 12:29:56 Nope, that didn't fix it. :( 13:00:40 Hmmm. 13:01:45 The isforth guy had similar complaints about stack pointer manipulation. 13:03:32 Out of curiosity, why do you want to consume 1K of stack space this way? 13:04:18 To provide a temporary data stack for the "Forth"-code I'm benchmarking. 13:04:37 Without having to go through the rigamorole of providing a 100% fully-equipped Forth environment. 13:13:08 Did you cross a page boundary with the 'sub esp,1024'? 13:15:20 It's possible, I don't know. 13:20:38 extern int doit(int x, char *); 13:20:38 int somefunc(int y) 13:20:39 { 13:20:39 char buf[1024]; 13:20:41 return doit(y, buf); 13:20:41 } 13:20:59 via: gcc -c check.c -O 13:21:03 gives: 13:21:12 00000000 : 13:21:12 0: 55 push %ebp 13:21:13 1: 89 e5 mov %esp,%ebp 13:21:13 3: 81 ec 10 04 00 00 sub $0x410,%esp 13:21:16 9: 8d 85 f8 fb ff ff lea 0xfffffbf8(%ebp),%eax 13:21:16 f: 50 push %eax 13:21:16 10: ff 75 08 pushl 0x8(%ebp) 13:21:17 13: e8 fc ff ff ff call 14 13:21:19 18: c9 leave 13:21:21 19: c3 ret 13:22:37 * kc5tja nods 13:23:17 Notice the push before the call. 13:23:28 Yes. 13:23:35 I know how C calls work. 13:24:04 I suspect that you might have crossed the page boundary with the sub, and linux had not yet commited the physical page. 13:24:05 I'm not allocating the buffer THEN calling the code, I'm allocating the buffer WITHIN the code. 13:24:50 But yet, even if it does such, the above code (assuming doit() is written in C) will work flawlessly. 13:25:24 Hence my consternation. 13:25:26 I suspect that it traps the fault, sees the PUSH, commits the page, and restarts the instruction. 13:25:47 Yes, but it doesn't need to inspect instructions for this to happen. 13:26:03 x86 records enough state to enable the host OS to expand the stack as needed. 13:26:13 (one of the few things it does correctly) 13:26:34 (amazingly enough, that is) 13:27:11 Sure, but the Linux kernel might consider an error writing off the edge of the stack with anything but a PUSH. 13:27:26 Or a CALL, which is what I'm doing. 13:27:48 Change doit() to be a void doit(void), and you'll see it doesn't push anything before calling it. 13:30:13 0: 55 push %ebp 13:30:13 1: 89 e5 mov %esp,%ebp 13:30:14 3: 81 ec 08 04 00 00 sub $0x408,%esp 13:30:14 9: e8 fc ff ff ff call a 13:30:18 Hmmm. 13:31:34 So, I'm at a total loss. There is nothing at all in the Linux FAQs about this. 13:31:46 The Assembly HOWTO was enlightening, but doesn't help me find the problem. 13:31:54 I *CAN* go straight to the raw kernel interface though. 13:32:04 So whatever problems exist appears to be purely and utterly in the C runtime environment. 13:32:24 You wrote your code in NASM? 13:32:31 Which, of course, defeats the purpose of why I'm even trying to write it for Linux to begin with. 13:32:35 yes 13:32:49 What does objdump -D of your .o file have to say? 13:33:00 It's a bit big. 13:33:18 I don't need the whole thing :-) 13:33:47 Nothing. 13:33:54 It says it's an ELF file, and that's it. 13:34:06 There we go. 13:34:09 What do you want to know? 13:34:31 I want to see the dumped part of your call to Foo. 13:34:50 (morbid curiosity) 13:35:40 0: 55 push %ebp 13:35:40 1: 89 e5 mov %esp,%ebp 13:35:40 3: 81 ec 00 04 00 00 sub $0x400,%esp 13:35:40 9: e8 18 00 00 00 call 26 13:35:40 e: e8 13 00 00 00 call 26 13:35:42 13: e8 0e 00 00 00 call 26 13:35:43 18: e8 09 00 00 00 call 26 13:35:45 1d: e8 04 00 00 00 call 26 13:35:47 22: 89 ec mov %ebp,%esp 13:35:51 24: 5d pop %ebp 13:35:53 25: c3 ret 13:36:22 and: 13:36:30 00000026 : 13:36:30 26: e8 d7 00 00 00 call 102 13:36:30 2b: e8 d2 00 00 00 call 102 13:36:30 30: c3 ret 13:37:03 dot just prints a dot to the screen using Linux system call interface. 13:38:02 --- join: a7r (~a7r@206.72.82.135) joined #forth 13:38:17 It looks sane to me. 13:38:27 Yeah. 13:38:34 There's no reason why it shouldn't work. 13:38:44 Now if I change dot to use libc instead of system call interface, it breaks. 13:38:57 oi 13:39:13 You mean it works with the kernel API and not with libc? 13:39:31 For the purposes of printing a humble dot on the screen, yes. 13:39:59 But I save all the registers I need to save when calling libc, and it still doesn't print, even when I fprintf to stderr. 13:40:10 --- join: tathi (~josh@pcp02123722pcs.milfrd01.pa.comcast.net) joined #forth 13:40:31 But this is actually unrelated to my initial problem, which I can probably at least have a chance of debugging now that I can print a dot to the screen. 13:40:44 But goddammit, how can I get any networking done if I can't even call fprintf?! 13:41:30 more horribly weird bugs kc5? 13:41:47 If you want to use the C runtime at all, you'll have an easier time if you have a C main() and drop into your own code from there. 13:42:01 * kc5tja cries!!! I DO!! 13:42:15 But that's not the point!!! 13:42:35 The point is, my code crashes under Linux, with no obvious explanation why. 13:42:48 SO, I decided to insert print statements to trace execution. 13:42:57 Those print statements DO NOT WORK> 13:43:13 The calls to fprintf are exactly liek those produced by a C compiler. 13:43:25 Inspected by me from the output of GCC directly. 13:43:48 Have you tried using gdb? 13:43:54 yes 13:44:59 --- quit: ChanServ (Shutting Down) 13:45:04 Ooops. 13:45:17 --- join: ChanServ (ChanServ@services.) joined #forth 13:45:17 --- mode: leguin.freenode.net set +o ChanServ 13:46:01 kc5tja: I don't know how else to help short of my running your code in a debugger. I'd love to volunteer, but I don't have that much time right now. 13:46:16 That's OK. 13:46:36 Keep your chin up, mate! 13:46:45 I'm starting to feel that working within Linux is going to be more trouble than its worth, and that it'd perhaps be a better use of my time to go straight to naked hardware. 13:47:31 If I have to replicate every damn library I want to use under Linux within Linux, I may as well just rewrite the damned code to run under my own host environment. 13:48:17 I think that once you've solved the library problem once you won't need to do it again. 13:48:22 It's either that, or take a *severe* performance hit and define a byte-code interpreter in C, with the Forth environment compiling to bytecode. 13:48:41 But you definitely have a long row to hoe to get there. 13:48:54 Exactly, and I *SHOULDN'T* have a long row to hoe. 13:49:06 Dude, the x86 has only 8 GPRs. 13:49:14 I can configure them in only so many ways! 13:49:37 There should be *zero* cause for fprintf to not work from my assembly code, but works from within C. 13:49:38 I disagree. The x86 EABI and C-runtime has many complexities. 13:49:57 You just need to find the one you've tripped over. 13:50:03 Well, I just looked at the Linux Assembly HOWTO, and it vindicates the correctness of my code. 13:50:44 It doesn't work, so you can draw one of two conclusions: you didn't do it correctly, or the HOWTO has it wrong :-) 13:52:14 Again, there are only so many ways for this to work. 14:01:57 OK, I managed to get fprintf working, after searching further on the Internet. I also managed to get dolit and drop working as well. 14:04:03 What did you have to do? 14:05:00 change push stderr to mov eax,[stderr] push eax 14:05:13 Now I'm debugging the actual cause of failure in my code. 14:05:25 Got dup, drop, and a bunch of other "words" working. 14:06:47 Ah, you got bit by the variable dereference. 14:08:15 Yeah, but I'm not having much additional luck with the bug I'm trying to diagnose now. 14:20:46 OK, looks like I got the bug tracked down and squashed. 14:21:08 The results are impressive though. :) 14:21:31 :-) 14:21:38 PURE subroutine threading is about as fast as GCC without optimization -- a tad bit slower, but still within the ball-park. 14:21:49 Oops 14:21:52 OK, about twice as slow. 14:22:21 GCC without -O3 runs through the benchmark at 15 seconds; Pure subroutine threading, using EBP to store data stack pointer, runs at 38 seconds. 14:22:29 But it's still *DAMN* good, I think. 14:22:36 But, the benchmarks must go on. 14:23:26 You have to do optimization or pure STC will not perform well. 14:23:50 heh: I said "optimization" and "pure STC" in the same sentence. 14:24:03 * TreyB needs to go on vacation. 14:25:32 --- quit: mur ("MURR! save the http://rainforest.care2.com/ (click url there)") 14:33:13 Well, that's why I'm benchmarking. 14:33:19 I'm deliberately starting with the slowest stuff first. 14:34:32 You should get pretty far by inlining the usual stack operators. 14:35:08 --- join: crc (~crc@ACA7F81A.ipt.aol.com) joined #forth 14:35:47 Thanks for the chat. Good luck. 14:40:04 Well, that's what I'm hoping. : 14:40:05 :) 14:40:25 Basically, what this is all boiling down to is, should I use EBP or ESI to house the data stack pointer? 14:40:40 There might be advantages and disadvantages to each, and I want to measure their effects early. 14:43:23 Gahh, now I have to debug a problem with the ESI code's implementation of store. :( 14:47:57 Problem was in OVER, actually. :/ 14:48:01 But it's fixed. 14:52:27 Wow. :) 14:52:50 Using ESI for the data stack is a sure-fire winner for (in)direct-threaded and subroutine-threaded implementations. 14:53:03 It is consistently 17% (average) greater performance. 15:17:49 w00t!!!! 15:18:05 Inlined code using ESI is 200% faster than the output from GCC with -O3. 15:36:14 nice 15:36:19 you go, kc5tja 15:37:34 :) 15:37:49 Final test is now in. 15:38:06 Even using EBP and exchanging EBP and ESP all the time, it's an average of 1.8 times faster than GCC's best output 15:38:35 But using ESI (or even EBP without using stack instructions) results in a 17% performance increase still. 15:38:55 Here's a sample output: 15:39:02 Baseline (GCC): 8539999 us 15:39:05 Subroutine Threaded (EBP): 41309999 us 15:39:05 Subroutine Threaded (ESI): 35919999 us 15:39:05 Native Code (EBP): 4769999 us 15:39:05 Native Code (ESI): 4009999 us 15:39:27 Note that native code (ESI) is 2.17 times faster than GCC's best. :) 15:41:09 --- quit: crc ("I was using TinyIRC! Visit http://www.tinyirc.net/ for more information.") 15:41:31 This test was run on an 800MHz AMD Athlon (original K7 design) with 640MB of RAM. 15:53:12 kc5tja: will you put up a page or Email me a tarball with your "native" and STC tests, please? 15:54:36 TreyB: I have a ZIP file of it. What's your e-mail? I do intend on putting a page up soon, on the bespin site. 15:54:54 trey@treysoft.com 15:55:02 Hold please... 15:58:08 OK, on its way. 16:02:46 Thanks. 16:03:11 I had a friend just try it on his P4-M laptop, at 2.2GHz. Interested in seeing his numbers? 16:03:18 Sure. 16:03:27 Baseline (GCC) 4749999 us 16:03:27 Subroutine Threaded (EBP) 8749999 us 16:03:27 Subroutine Threaded (ESI) 7349999 us 16:03:27 Native Code (EBP) 1579999 us 16:03:27 Native Code (ESI) 1879999 us 16:03:50 * TreyB will try on his Athlon 2400+ under VMWare. 16:04:21 eerk -- clock speeds getting high enough that Linux timer resolution starts becoming a significant factor. :D 16:04:38 If you get weirded out numbers, I can make you a version that runs the software for longer, thus getting more accurate results. 16:04:58 Yeah, you have to get the instruction timing registers and use those instead. 16:11:15 Baseline (GCC): 37769999 us 16:11:16 Subroutine Threaded (EBP): 97719999 us 16:11:16 Subroutine Threaded (ESI): 66709999 us 16:11:17 Native Code (EBP): 26009999 us 16:11:17 Native Code (ESI): 17979999 us 16:11:55 PPro 150MHz 16:16:44 Cool. :) 16:16:55 Yeah, I didn't want to bother looking up the opcodes for those. :) 16:17:05 This seems to work decently enough. 16:18:04 --- quit: w1k1 ("!") 16:18:10 My friend with a P4 shows that native code offers a 3x boost in performance instead of 2x boost. But otherwise, the numbers are astonishingly congruent with expectations. 16:19:27 Baseline (GCC): 5527373 us 16:19:27 Subroutine Threaded (EBP): 18017640 us 16:19:28 Subroutine Threaded (ESI): 17972657 us 16:19:28 Native Code (EBP): 5914067 us 16:19:29 Native Code (ESI): 2880866 us 16:19:54 What platform? 16:20:11 Athlon 2400+ under VMWare on a Win2K host. 16:20:18 Ahh 16:21:07 I'm sorry; I have to get going. I have a headache, so I need to lie down for a bit. Then I need to get some food. err....that should be the other way around. :) 16:21:12 Had the headache since yesterday. :/ 16:21:17 * kc5tja hates migranes... 16:21:27 * TreyB has to take his family to dinner and then light some fireworks. 16:21:43 * kc5tja is going to stay home and listen to ham radio/shortwave radio for tonight. 16:21:45 Take it easy. 16:21:51 Traffic is going to be pretty bad anyway. 16:21:53 OK, thanks. :) 16:21:58 have fun 16:22:35 Heheh :D 16:22:58 * kc5tja is still doing the happy dance from his coding experiment.... I definitely now know exactly what kind of code to produce. 16:54:56 --- quit: tathi ("leaving") 17:17:36 back -- currently eating. 17:24:22 --- join: TheBlueWizard (TheBlueWiz@207.111.96.11) joined #forth 17:24:22 --- mode: ChanServ set +o TheBlueWizard 17:24:29 hiya all 17:27:23 re tbw 17:27:33 hiya kc5tja 17:27:53 how's your project going? just curious 17:28:12 hi TheBlueWizard 17:28:18 Very well indeed. 17:28:18 hiya Herkamire 17:28:23 :) 17:29:48 I still haven't decided how my blocks of source should work 17:30:05 how should I keep track of how much source is in there? 17:30:54 I'm not sure I understand the question? 17:31:15 a block is 1024 bytes, so thats 512 source tokens 17:31:40 I probably won't be using all 512. 17:32:12 how should I make LOAD interpret exactly the number of source tokens I have in that block? 17:33:04 One possibility is to define a "null token" that acts as a sentinel. 17:34:16 yeah. I don't like that one though. 17:34:40 maybe because I haven't figured out how to do it a way I like :) 17:40:01 --- quit: a7r (Read error: 110 (Connection timed out)) 17:43:50 --- join: Jim7J1AJH (~jwt@n1.dskk.co.jp) joined #forth 18:03:15 --- join: a7r (~a7r@206.72.82.135) joined #forth 18:05:43 hiya a7r 18:06:00 TheBlueWizard: hol 18:06:01 a 18:07:07 :) 18:08:05 --- join: a7r_ (~a7r@206.72.82.135) joined #forth 18:28:39 well, I must go...bye all 18:29:02 OK 18:29:05 Laters! :) 18:29:25 bye kc5tja :) 18:29:29 --- part: TheBlueWizard left #forth 18:30:15 Baseline (GCC): 9039999 us 18:30:16 Subroutine Threaded (EBP): 40349999 us 18:30:16 Subroutine Threaded (ESI): 34729999 us 18:30:16 Native Code (EBP): 4739999 us 18:30:16 Native Code (ESI): 3969999 us 18:30:16 Raw Assembly: 1979999 us 18:30:20 Updated numbers . . . 18:30:28 Raw assembly is the fastest I can produce. 18:30:57 My roommate can probably produce a version that's faster by using the FPU or MMX instructions. 18:31:11 * kc5tja isn't familiar with techniques for using the FPU/MMX instructions. 18:36:23 --- quit: a7r_ (Read error: 110 (Connection timed out)) 18:48:03 kc5tja: the Baseline is using C code? 18:48:44 food, it does the body good :) and the mood 18:49:27 OOPS...I discovered a pretty critical bug in the code. :( 18:49:38 The C code goes through 4MB of data, while the Forth code goes through only 1MB. 18:52:28 Fixed that, and the Forth code isn't quite so fast anymore. :D 18:52:41 But, it's as fast as GCC without any -O options of any kind. 18:53:07 So it is still about twice as slow as raw assembler though. 19:00:17 oops :) how fast is the Baseline now? 19:01:17 can I see the C code? I'm curious 19:09:11 --- quit: skylan (Read error: 54 (Connection reset by peer)) 19:09:30 It's the same. 19:09:36 Yeah. E-mail address? 19:09:48 Actually hold on... 19:10:05 roommate is helping me to optimize the raw assembly version to take cache access into account. 19:11:43 --- join: skylan_ (sjh@nwc57-182.nwconx.net) joined #forth 19:13:06 --- nick: skylan_ -> skylan 19:13:11 oh, you bumped the forth up to 4MB. 19:17:59 Yeah. 19:41:29 --- part: Jim7J1AJH left #forth 20:13:13 --- quit: a7r (Read error: 60 (Operation timed out)) 21:11:56 --- join: a7r (~a7r@206.72.82.135) joined #forth 21:49:11 Final performance test source is now accessible on the #Forth website. 21:49:15 Check news items for details. 22:16:20 --- quit: Herkamire ("bedtime") 22:22:56 Going out. 22:22:59 --- nick: kc5tja -> kc-away 22:42:07 --- join: Serg_Penguin (Serg_Pengu@212.34.52.140) joined #forth 22:42:13 --- quit: Serg_Penguin (Client Quit) 23:10:01 re.. 23:21:57 --- nick: kc-away -> kc5tja 23:22:05 Back 23:22:55 a7r: Not sure if you noticed or not, but FS/Forth for Linux will be comparable in speed to GCC 23:23:09 kc5tja: elite 23:23:37 that sounds pretty impressive 23:41:30 * kc5tja nods 23:42:06 Granted GCC is 2.2x faster than FS/Forth's code when used with -O3 -mcpu=athlon (for my Athlon boxes; speedup varies across processor line of course). 23:42:31 But still, a factor of 2 isn't going to show itself unless you're working with a *LOT* of data. 23:43:15 * kc5tja is really pleased with the outcome, considering the generated code is grossly under-utilizing the hardware. :D 23:43:20 And is very memory-intensive. 23:43:30 I have actual numbers posted on a website. 23:43:34 (if you're interested) 23:51:28 http://forum.forth.bespin.org/viewtopic.php?t=8 23:59:59 --- log: ended forth/03.07.03