flat assembler
Message board for the users of flat assembler.
Index
> Tutorials and Examples > [Abakis] Ultimate New Language! Macro EVOLUTION Goto page 1, 2, 3 Next |
Author |
|
m3ntal 19 Oct 2014, 06:07
[Abakis] Ultimate New Language! Macro EVOLUTION
Abakis; Easiest, most evolved macro language. Created entirely with FASM's preprocessor and directives. Ultra compact portable syntaxes for maximum production within minimal timeframe. Multi-statements specify more information for greater optimizations on other CPUs. Lightweight package. Reduced library. Includes special FASM (ASSEMBLER.EXE) to build it (?if/?while/?x is the only difference). Abakis Web Site (Syntax Highlighted) Download Abakis SYNTAXES (u8) is the default for *p if not specified by (cast) Code: while c, c=*p++, endw, p-s, p-- . p=a, q=b, n>>>2 loop n, (u32) *p++=*q++, endl while s<e, c=*s, *s++=*e, *e--=c, endw loop n, c=*s++, *p++=c if c=0, break, end endl, p-- while c, c=*s++, *p++=c, endw, p-- if n=0, *p++='0', *p=0 return s end while c=d, c=*p++, d=*s++ if c=0, break, end if d=0, break, end endw, p=c, p-d while n, x=n, x&1, x+'0' . *p++=x, n>>>1 endw, *p=0 forever, c=*p++ if c=0, return n, end . x=n, x<<2, n+x, n+n, n-'0', n+c endfv Code: ; memory copy 32BIT function memory.copy, a, b, n alias p=r0, q=r1 . p=a, q=b, n>>>2 loop n, (u32) *p++=*q++, endl endf ; text.n t - get length, # characters function text.n, t alias p=r0, s=r1, c=r2 . p=t, s=p, c=1 while c, c=*p++, endw, p-s, p-- endf ; text.copy a, b - standard copy with ; 0 after. return advanced address function text.copy, a, b alias p=r0, s=r1, c=r2 . p=a, s=b, c=1 while c, c=*s++, *p++=c, endw, p-- endf ; text.copy.n a, b, n - copy with maximum ; size specified. return & function text.copy.n, a, b, n alias p=r0, s=r1, c=r2 . p=a, s=b loop n, c=*s++, *p++=c if c=0, break, end endl, p-- endf ; convert 32BIT binary number to text function b2t, n, t alias p=r0, x=r1 . p=t if n=0, *p++='0', *p=0 return end while n, x=n, x&1, x+'0' . *p++=x, n>>>1 endw, *p=0 text.reverse t endf ; load/save memory and text function load.file, name catch .0 try open name try file.p=allocate file.n try read file.p, file.n close return file.p .0: flush close endf 0 function save.file, name, p, size catch .0 try create name try write p, size close return 1 .0: close endf 0 function append.file, name, p, size catch .0 open name if false try create name else seek 0, SEEK.END end try write p, size close return 1 .0: close endf 0 function load.text, name alias p=r0 catch .0 try open name . r0=file.n, r0++ try file.p=allocate r0 try read file.p, file.n close . p=file.p, p+file.n, *p=0 return file.p .0: flush close endf 0 function save.text, name, t text.n t save.file name, t, r0 endf Code: ; ABAKIS EXAMPLE. SEE \INCLUDE\ include 'z.inc' text t(64), s(64), f='LOG.TXT' text m(64)='NOItUlOVe ReLBmESsa SikaBa' function test.text text.copy t, m say t text.reverse t text.upper t text.attach.c t, '!' endf function test.number say.n 4294967295 say.h 0ABCDEF12h say.h 0FFFFFFFFh say.b 11110000111100001111b endf function test.memory locals p try p=allocate 33 memory.zero p, 33 memory.set p, '1234', 32 say p destroy p endf 1 function test.file locals n get n=text.n t try create f write t, n close try open f read s, n say s close execute f endf 1 function test.io test.memory if false say 'Memory allocation error' return 0 end test.file if false say 'File I/O error' return 0 end endf 1 function main test.text test.number try test.io endf I recently improved LANGUAGE.INC greatly. It's been about a year since I've edited this file. Still unfinished and untested. Quote: * Rewrote variables. All standard names like byte, char, int/eger, void. MEANING Abakis meaning: 1. "Abacus", oldest "calculator". 2. "...Kis", "Keep it simple". 3. It will have an ancient egyptian theme to represent the evolution of language (hieroglyphics). The .EXE icon will be an Anhk or Eye of Horus symbol. One of the mythical characters is named "Anubis", similar to "Abakis". He would be a good figure to use on the box cover illustration and advertisements.
Last edited by m3ntal on 19 Oct 2014, 16:56; edited 1 time in total |
||||||||||
19 Oct 2014, 06:07 |
|
TmX 19 Oct 2014, 17:05
Hi m3ntal,
Looks cool. Anyway, it's interesting to see that you modified FASM in order to support your language. Hopefully you don't mind to share the modified code as well |
|||
19 Oct 2014, 17:05 |
|
Matrix 19 Oct 2014, 21:06
TmX wrote: Hi m3ntal, Since he is not selling anything(yet) I was thinking about he is trolling |
|||
19 Oct 2014, 21:06 |
|
m3ntal 22 Oct 2014, 05:14
UPDATE: Download ABAKIS. Fixed typos. Some improvements. Windows, minimal graphics (DRAW.INC) with clipping.
Code: if n=0, *p++='0', *p=0, return 0, end while n, x=n, x&1, x+'0', *p++=x, n>>>1 endw, *p=0, s=p, x*1000 loop, c=*p++ if c=0, return n, end . x=n, x<<2, n+x, n+n, n-'0', n+c endl text can create arrays of pointers to literal 'text' with optional alignment, IDs and prefixes (NAME.*). All with one keyword. Code: text ta[]= '123', 'ABC', 'XYZ' text names[](8)= 'ann', 'kim', 'sue' text xyz[]= ID.A='A', ID.B='B', ID.C='C' text theme.names[THEME.*]= BLACK='Black', WHITE='White', SILVER='Silver' Code: ;;;;;;;;;;;;;;;;;;;; DRAWING ;;;;;;;;;;;;;;;;;;;;; ; address &vga[(y*(screen.w*4))+(x*4)] ; (y*(screen.w*(bpp/8))))+(x*(bpp/8)) ; (y*(screen.w*(bpp>>>3))))+(x*(bpp>>>3)) function vga.xy, x, y alias a=r0, b=r1, n=r2 . a=screen.w, a*4, a*y, b=x, b*4, a+b, a+vga endf ; erase screen with color/r0... function clear.screen, c alias p=r0, n=r1, z=r2 . p=vga, n=screen.n, z=c loop n, (u32) *p++=z, endl endf ; draw pixel function draw.pixel, x, y, c alias p=r0, z=r1 try clip.pixel x, y vga.xy x, y . z=c, (u32) *p=z endf 1 ; draw horizontal line function draw.line.h, x, y, n, c alias p=r0, z=r1, w=r2 . p=&x, z=&y, w=&n try clip.line 'h', p, z, w vga.xy x, y . z=c loop n, (u32) *p++=z, endl endf 1 ; draw vertical line function draw.line.v, x, y, n, c locals swb alias p=r0, z=r1, h=r2 . p=&x, z=&y, h=&n try clip.line 'v', p, z, h vga.xy x, y . z=c, swb=screen.pitch loop n, (u32) *p=z, p+swb, endl endf 1 ; draw solid rectangle function draw.box, x, y, w, h, c locals i try visible x, y, w, h . i=y, i-- loop h, i++ draw.line.h x, i, w, c endl endf 1 Code: include 'a.inc' use interface !on create ; ... !end !on draw locals x, y, w, h clear.screen ROYAL.BLUE . x=128, y=128, w=screen.w, w-256 . h=screen.h, h-256 draw.box x, y, w, h, POWER.BLUE draw.outline x, y, w, h, WHITE !end !on key if key.event='k' say 'Key Press' end !end !on mouse if mouse.event='c' say 'Mouse Click' else.if mouse.event='rc' minimize.window end redraw !end Code: ;;;;;;;;;;;;;;;; WINDOW PROCEDURE ;;;;;;;;;;;;;;;; function _window.procedure, window, message, wp, lp alias m=r0 . m=message, event.id=0, mouse.double=0 if m=WM_PAINT get _dc=BeginPaint _hwnd, _ps redraw EndPaint _hwnd, _ps go .default else.if m=WM_COMMAND calle command else.if m=WM_KEYDOWN . key=wp, event.id='k', key.event='k' if exit.if.esc if wp=K.ESCAPE SendMessageA window, WM_DESTROY, 0, 0 end end .key: calle key return 0 else.if m=WM_KEYUP . key=NO, event.id='k', key.event='r' go .key else.if m=WM_CHAR . key=wp, event.id='k', key.event='c' go .key else.if m=WM_MOUSEMOVE . mouse.event='m' if mouse.1 if not mouse.drag . mouse.drag=YES,\ mouse.drag.x=mouse.x,\ mouse.drag.y=mouse.y end end .mouse: . event.id='m', r0=lp, r1=r0,\ r0&0FFFFh, mouse.x=r0,\ r1>>16, r1&0FFFFh, mouse.y=r1 calle mouse if mouse.event='m' . mouse.px=mouse.x,\ mouse.py=mouse.y end return 0 else.if m=WM_LBUTTONDOWN . mouse.event='c', mouse.1=YES,\ mouse.drop=NO go .mouse else.if m=WM_LBUTTONUP . mouse.event='r', mouse.1=NO if mouse.drag . mouse.drop=YES,\ mouse.drop.x=mouse.x,\ mouse.drop.y=mouse.y,\ mouse.drag=NO end go .mouse else.if m=WM_LBUTTONDBLCLK . mouse.double=YES go .mouse else.if m=WM_RBUTTONDOWN . mouse.event='rc', mouse.2=YES go .mouse else.if m=WM_RBUTTONUP . mouse.event='rr', mouse.2=NO go .mouse else.if m=WM_MOUSEWHEEL . mouse.event='w', r1=wp,\ r1>>16, mouse.wheel=r1 go .mouse else.if m=WM_CREATE calle create jmp .default else.if m=WM_DESTROY .destroy: calle destroy PostQuitMessage 0 jmp .default else go .default end .default: DefWindowProcA \ window, message, wp, lp endf Code: ; SYSTEM.INC... function os.create.vga, w, h alias p=r0, x=r1 set.screen screen.w, screen.h, screen.bpp try vga.hbm=CreateBitmap \ screen.w, screen.h, 32, 1, vga memory.zero vga.bmi, BITMAPINFOHEADER.$ . vga.bmi.biSize=BITMAPINFOHEADER.$ . vga.bmi.biWidth=screen.w . x=screen.h, neg x, vga.bmi.biHeight=x . vga.bmi.biPlanes=1, vga.bmi.biBitCount=32 ShowCursor 0 endf function os.show.vga SetDIBits _dc, vga.hbm, 0, screen.h,\ vga, vga.bmi, 0 draw.bitmap.w vga.hbm, 0, 0, screen.w, screen.h . vga.rect.left=0, vga.rect.top=0,\ vga.rect.right=screen.w,\ vga.rect.bottom=screen.h InvalidateRect _hwnd, vga.rect, 0 endf Updated Visual Menus with 7 themes. No time for responses. I must quit programming for a while and make $. Last edited by m3ntal on 22 Oct 2014, 08:00; edited 1 time in total |
|||
22 Oct 2014, 05:14 |
|
m3ntal 22 Oct 2014, 07:58
TmX: Same as FASM with the optional aliases ?if/?while/?repeat/x so that if/while/x can be redefined for runtime. It will assemble any FASM code because if/while/x have their original meaning until they get redefined in LANGUAGE. On my phone.
Edit: Examples do not exit and I can't update now. Solution: Insert "exit" after "call !main" at the end of SYSTEM.INC. Accidentally removed it. I do not have internet and must go outside with my phone to respond and update examples (AndFTP) on a 4.3" screen. |
|||
22 Oct 2014, 07:58 |
|
PeExecutable 24 Jul 2015, 00:44
Horus will not be happy for this! (Moses will come against you and split it apart)
|
|||
24 Jul 2015, 00:44 |
|
PeExecutable 22 Aug 2015, 09:57
Horus sent a helper to achieve the goal, and the goal was achieved with the help of Horus.
http://en.file-upload.net/download-10856841/ItIsDone_RisenAndCanAdapt.mp4.html |
|||
22 Aug 2015, 09:57 |
|
codestar 22 Aug 2015, 21:23
PE: What are you talking about? Horus loves me Artists create imaginative characters like Zeus and Horus and you take them literally If there is a "Source of Goodness", then we are like receivers of this information and all artistic expression derives from it - Wizard of OZ, He-Man, Transformers, Abakis, Positive Atheism, Universalism. All have good positive messages. No disrespect. My honest truth.
No one here wanted to talk about programming so I gave up. |
|||
22 Aug 2015, 21:23 |
|
PeExecutable 23 Aug 2015, 21:04
codestar wrote: No one here wanted to talk about programming so I gave up. 1. Newcomers who come to fasm are primarily very interested in fasm and want to learn fasm primarily (first) perhaps later they will look at something like what you have designed 2. Those who are already here are mostly "elites", and they don't like to learn new languages, some of them do still, in rare cases 3. Abakis isn't "really" assembly and that pisses some people off 4. Being dependent on an underlying assembler with a new "language" on top of it creates annoying dependencies, specially if the author of the top layer isn't serious (I don't know whether you are serious or not, but it can be an annoyance) 5. If you change your mind and re-design your language often, people have to re-learn it, if this is a bad habit, some people may be put off by that and decide to abandon the language 6. If the language is highly subjective to the author, it might piss some people off. (If you don't care about making it easy to understand but do everything to make it easy for yourself to understand, the narcisistic designer, I'm not saying you are, but this is a very big annoyance with those who are) 7. If you brag about it, people may just leave your language just to punish you. There is nothing wrong about bragging, but the destructive kind of bragging where you put down other designers of similar projects. 8. People need a language designer who is optimistic and give inspiration and optimism to the user, if you find yourself to be highly destructive, that itself may trigger people to abandon Abakis. Abakis need more association with assembly and a little less toward HLL language design. It needs stability (stability = solid base that doesn't change too often). And you need to get rid of the horus shit, languages should not be associated with religion. The last thing a buddhist want is to have Horus on his mind. Neutrality and some seriousness. Good luck |
|||
23 Aug 2015, 21:04 |
|
codestar 24 Aug 2015, 16:14
Quote: 1. Newcomers who come to fasm are primarily very interested in fasm and want to learn fasm primarily (first) perhaps later they will look at something like what you have designed Quote: 2. Those who are already here are mostly "elites"... Quote: 3. Abakis isn't "really" assembly and that pisses some people off Quote: 4. Being dependent on an underlying assembler with a new "language" on top of it creates annoying dependencies, specially if the author of the top layer isn't serious (I don't know whether you are serious or not, but it can be an annoyance) Quote: 5. If you change your mind and re-design your language often, people have to re-learn it, if this is a bad habit, some people may be put off by that and decide to abandon the language Quote: 6. If the language is highly subjective to the author, it might piss some people off. Quote: ... the narcisistic designer, I'm not saying you are, but this is a very big annoyance with those who are) Quote: 7. If you brag about it, people may just leave your language just to punish you. Quote: There is nothing wrong about bragging, but the destructive kind of bragging where you put down other designers of similar projects. Quote: 8. People need a language designer who is optimistic and give inspiration and optimism to the user... Quote: ... if you find yourself to be highly destructive, that itself may trigger people to abandon Abakis. Last edited by codestar on 24 Aug 2015, 19:58; edited 3 times in total |
|||
24 Aug 2015, 16:14 |
|
PeExecutable 24 Aug 2015, 16:24
codestar wrote: Abakis doesn't claim to be assembly. You have a misconception that I want people to use Abakis. You see the difference there, hopefully. One thing you should be aware of is that if you are trying to create a HLL language, you should leave that for other HLL languages because the compiler can do a better job with HLL code. Assembly is a tool that is only useful under the scrutiny of very sharp coders or under the scrutiny of a very sharp compiler, anything in between becomes pollution. You should focus on creating something that makes assembly easier but that doesn't obfuscate the assembly, or you should develope a compiler. Anything else is probably a waste of time, probably. But that doesn't mean your language isn't beautiful, it looks attractive, I haven't used it yet. Memory.inc is lacking a MemMove function, if the memory addresses overlaps you can get very serious bugs with the memory copy function. Adobe had such a bug with their flash player a few years ago where they used memcopy instead of memmove, and it can be serious business, just telling Other than that, the allocate function, does it use heap, virtual or what, how can you specify that? When coding function that is not part of a performance critical path, it is better to use the memory functions that the OS provide, even if they are slower, you break dependencies and guarantees that they will work. RtlCopyMemory, RtlFillMemory, RtlZeroMemory, SecureZeroMemory etc. Only use your own if performance is an issue. One time copy/fill/zero events -> Use the OS functions. |
|||
24 Aug 2015, 16:24 |
|
PeExecutable 25 Aug 2015, 16:12
I looked through the system.inc but I didn't have much time, I just want to help you out
begin.message.loop: The first error is that it assumes the ANSI version of GetMessage, what if the user wants to use unicode? The second error is that the fail macro doesn't handle -1 errors on GetMessage, which is a very common newbie error. The third error is that it assumes the programmer is handling all windows, but if he wants to yield messages only from a particular window at a particular time, the parameter is wrong. The fourth error is, which isn't an error, it's just an optimization that can be performed, you run PeekMessage first and then GetMessage (to avoid a lock up), these calls requires 9 pushes on the stack, or 9 dword writes on the stack. You should use GetQueueStatus which requires only 1 push and it doesn't lock up. (Optimization for you). In a high peformance message loop, you're writing to memory at almost ten times the amount that you really need to. When it comes to system.inc, the window procedure has more of the important input messages handled near the bottom of the if/else clause, you should have the most frequently expected at the top of the list so they get handled first. You should avoid lookup buffers primarily, but it may just help you here, personally I would do a split-conquer (Cut in half, cut further in half, to reduce the list). The list is highly inefficient and you shouldn't load the parameters at the window proc entry, only load the message and then load whatever is needed for the specified messages if it hits. os.get.file.size skips the h.o dword and is limited to only file sizes of 4 GB. create.window.x loads icon which is limited to 32x32, if the user have icons larger they will not show up or gets downgraded. os.delay loops with GetTickCount and waste processing time, you should use Sleep to yield processing time to other processes. os.find file should turn off Wow64 file system redirection before searching so that it works on 64 bit versions of windows. You can not rely on importing api functions by ordinals, ordinals may change. There is a lot in there. I actually started to like the abakis project after looking into it. It looks interesting, but I don't have more time to study it, I'm busy studying fasm macros |
|||
25 Aug 2015, 16:12 |
|
codestar 28 Aug 2015, 09:39
Sorry, I don't do programming anymore.
Abakis is something else, the hardest language with the easiest, tightest, purest syntax for the craziest, most obsessive, perfectionist ("est" compared to all the languages I've seen). Most evolved "ASM macro language". All of this is hand-written by myself. Any "mistakes" you perceive are just "unfinished business; no time; process of evolution". LANGUAGE.INC is the only file that's needed, it hasn't been updated in a long time. Try writing some code. Try making a program. Abakis speaks in mysterious ways: Quote: "Use me, baby. I'm the best language, most beautiful and powerful there is, there's nothing better than me, I can prove it with numbers and measurements. Don't even look at C or I'll get jealous. You don't need her, I'll do everything for you" - Don't listen to her. She tells mostly truth that can be verified, but she's crazy, not perfect, has "issues", still needs safety and expressions. She's fun to play with at times, exciting and dramatic, but very "dangerous" and not the type who I would stay with. You can have her. I'm generous with abilities, knowledge, women, programs, languages, inventions, CPU designs, etc, things which I have an abundance of. |
|||
28 Aug 2015, 09:39 |
|
PeExecutable 28 Aug 2015, 14:48
There is nothing wrong with her.
It's the other guy. (Any mistake is unfinished business) Good luck with whatever you're doing |
|||
28 Aug 2015, 14:48 |
|
PeExecutable 29 Aug 2015, 17:48
Don't abandon programming, you'll only delay it because you will want to come back to programming again, and there are people on the forum who want you to stay, they are highly receptive and want you to stay, they will only become angry if you leave.
You've treated many people in here like trash for many years, and some of them are not angry with you at all, it's because they want you to stay even if you attack them. It's "magical" friendship there. I was attacked by a rosegarden once.... It is critical that you come back again, urgent. Btw. I'm studying the match macro these days. It's not really much to study, but it's one of those macros you can't skip. I see a match and it is a good match, it's not based on a virtual reality, the match is virtual at reality, you can irps to irp to go through white clumps of matter. |
|||
29 Aug 2015, 17:48 |
|
codestar 30 Aug 2015, 07:02
Thanks for your comments. Tengo buena medicina ahora y estoy feliz Muchas gracias El Chapo Chitown te ama.
Quote: You've treated many people in here like trash for many years In US, it's a joke to insult people, a game (Arsonal and Shotty, battle rappers, comedy). Quote: Btw. I'm studying the match macro these days. It's not really much to study, but it's one of those macros you can't skip. I see a match and it is a good match, it's not based on a virtual reality, the match is virtual at reality, you can irps to irp to go through white clumps of matter. Code: macro variable [p] { ; create integer variables common ; do this once... local m define m 0 ; did match occur? forward ; loop for each p... match v==n, p \{ ; assignment? use 2 == for = v dd n ; create variable define m 1 ; successful match \} match =0 v, m p \{ ; else, just name v dd 0 ; create variable, value=0 define m 1 ; successful match \} match =0, m \{ ; else, no match display 'Error' \} } Last edited by codestar on 30 Aug 2015, 15:09; edited 2 times in total |
|||
30 Aug 2015, 07:02 |
|
codestar 30 Aug 2015, 07:25
PE_Executable: I'm not one who needs help with programming. Does Michael Jordan need help learning how to play basketball? Of course, we all need help in one way or another. I don't have time to explain. For example, all functions are ASCII (not just GetMessageA), lookup tables are good optimizations, library is 32BIT, no 64BIT OS (W8 32BIT) and no Intel library I've ever released imports by ordinal (only ARM CE).
A real "mistake" is when I believe that some code is correct when it's not. In any library this size, there are many sections of code that could be improved but is not a "mistake". Advanced programmers make "mistakes" all the time and the percentage of errors increases with the volume of code that we write. Only those who never write code never make mistakes. I'm not so afraid to "miss" that I never throw a punch. It may be true that the "evil" we perceive in the world is "unfinished; process of evolution", the perfect system. In my code, I follow the true evolutionary process by "smart selection", tests and observation of results ("big pharma" does the opposite: alter, isolate and devolve). Personal: Please be careful, I learn so much about you, strengths and weaknesses, with the slightest interaction. I've only viewed 4 threads containing your messages and I believe I can name 2 movies that have personalities like yours: "Knowing" and "Sorcerer's Apprentice". You "know" these kinds of people? I'm not limited to information that you "reveal". Last edited by codestar on 30 Aug 2015, 11:49; edited 1 time in total |
|||
30 Aug 2015, 07:25 |
|
PeExecutable 30 Aug 2015, 09:52
Lookup tables are good in extremely small quantities. You can't live with them because if you do them regulary all over your code you rely in too much memory use and it's not sustainable. Cache and memory speeds vary between computers and when you use lookup tables you get too large "spikes" in the speed you get.
When you use lookup table on computer A you may get speed X, on computer B you get a totally different speed Y. That is why you should always try to avoid lookup tables and rely in cpu power, because the variation you get in cpu power is less problematic than the variation you get in memory speed. You should use lookup buffers if they are very small, up to 64 bytes and if you have a very few of them alltogether in your code. You don't want your program to jump up and down on the computers it will run on, and the only way to do that is to rely more in cpu than memory. When you're speaking about "mistakes", based on what you're saying it seems as if you're trying to distance yourself from that and don't want to have anything to do with that, but don't be angry with those who point out your mistakes, because it's your own mistakes, not theirs. I have got nothing to do with Christopher Hitchens We should join forces starcode. The elderly scrolls have gathered in a rebellion and they seek to compensate with stupidity. |
|||
30 Aug 2015, 09:52 |
|
codestar 30 Aug 2015, 12:19
Quote: You should use lookup buffers if they are very small, up to 64 bytes and if you have a very few of them alltogether in your code. Quote: When you're speaking about "mistakes", based on what you're saying it seems as if you're trying to distance yourself from that and don't want to have anything to do with that, but don't be angry with those who point out your mistakes, because it's your own mistakes, not theirs. Quote: We should join forces starcode. |
|||
30 Aug 2015, 12:19 |
|
Goto page 1, 2, 3 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.