7 ms·
Paint16b: A 16 byte paint program written in 12 lines
- jorisw 8y agoBe helpful if the page mentioned what language the program was written in.
- londons_explore 8y ago16 bit x86 assembly. It will run on DOS with a VESA framebuffer and mouse driver. Dosbox with it's default config should work fine.
- einr 8y agoNitpicking, but this is not a VESA mode, it is plain VGA mode 12h (640x480x16).
- klohto 8y agoIs assembly not common knowledge anymore?
- nf05papsjfVbc 8y agoI'm not even sure if C is.
- jacquesm 8y agoIt's interesting how many people would not recognize assembly language if shown a sample. In a way that is a statement as to how far compilers have come, that it is possible to produce perfectly good software that runs fast enough that only a limited number of people still has to know about the details of the underlying processor. And in the case of interpreted languages or JIT'd languages the lines get blurred a bit more but even there it is clear that whoever uses say 'numpy' does not need an understanding of the underlying operations to get through their working day. Higher levels of abstraction translate into higher productivity, in ever more rare cases it is worth breaking open those black boxes to go to work on the underlying plumbing.
- benj111 8y agoIn the parents defense 'assembly' isn't one thing. Every assembler has a different syntax, as does every chip family. The parent might be a master of 6502 ASM. And as that XKCD comic says. Everyone has to learn even the most obvious thing for the first time at some point.
- m0skit0 8y agoHm... If you know one assembly you can easily recognize when it is assembly, even if you don't know the specific architecture.
- vanderZwan 8y agoNot if it is your first time seeing assembly.
- dpcx 8y agoDoesn't that then imply that you don't know assembly?
- vanderZwan 8y agoBlargh, I somehow read that as "if you don't know assembly" instead of "if you know one assembly".
- odn86 8y agoI'm the worst type of bootcamp web developer you can imagine. I only knew it was Assembly because i once looked at the apollo guidance computer's source code.
- hondadriver 8y agohttps://xkcd.com/1053/ https://xkcd.com/1053/
- klohto 8y ago
- thanosnose 8y agoThere is a significant portion of developers ( particular web and app ) and IT staff who never studied computer science in college but instead moved into programming/IT mid career. Most of them probably never heard of or seen assembly code. However, I would be shocked if anyone who went through a CS program wasn't aware of assembly programming.
- AstralStorm 8y agoCS tends to be algorithms not low level programming. Unlike say robotics or electronics.
- vectorEQ 8y agolots of 'programmers' don't even know what a debugger or a cpu is xD let's not talk about common knowledge in 2018 please its depressing :D
- reaperducer 8y agoLast week I had to explain to an IT guy what a tractor feed printer is. He'd never heard of "tractor feed."
- taejo 8y agoASM is arguably not obsolete technology, while tractor feed pretty clearly is.
- m0skit0 8y agox86 16-bit assembly using MS-DOS system calls.
- Sharlin 8y agoIt's obvious in the context of that wiki. From the front page: > SizeCoding.org is a wiki dedicated to the art of creating very tiny programs for the 80x86 family of CPUs. By "very tiny programs", we mean programs that are 256 bytes or less in size, typically created by members of the demoscene as a show of programming skill. The size of these tiny programs is measured by their total size in opcode bytes, and are usually presented as executable .COM files to be run in pure DOS, a DOS VM running inside another operating system, or an emulator that can run DOS such as DOSBox.
- voltagex_ 8y agohttps://www.pouet.net/prod.php?which=63826 https://www.pouet.net/prod.php?which=63826 has download links. In theory if someone were to put this onto archive.org you could use the JS version of DosBox to try it out.
- benj111 8y agoAnd if you liked that http://www.hugi.scene.org/compo/compoold.htm http://www.hugi.scene.org/compo/compoold.htm And something I found useful https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html https://www.muppetlabs.com/~breadbox/software/tiny/teensy.ht... It really is quite amazing how small you can make things when you try. Then you realise you're wasting most of a disc sector, and the thing you have is unportable and unmaintainable. But still, being able to look at a binary and know what every byte does, being unconstrained by the rules of a language is liberating.
- dalf 8y agoThanks ! Is there anything about Tetris like game ? I found this : https://developers.slashdot.org/story/12/02/19/1351213/tetris-in-140-bytes https://developers.slashdot.org/story/12/02/19/1351213/tetri... but it's in Javascript. A long time ago I wrote this : https://github.com/dalf/stetris/blob/master/STETRIS-UTF8.ASM https://github.com/dalf/stetris/blob/master/STETRIS-UTF8.ASM
- stuartmalcolm 8y ago> assume ah=0; assume bx=0 Hmm. So the second time this program is run, it will fail?
- chris_overseas 8y agoNo, AFAIK MS-DOS always initialises it to zero before starting the program. I'm trying to find a better reference, but I think this[0] effectively explains what state the registers are in on entry to your program. Edit: I take that back. According to [1]: .COM-format executables begin running with the following register values: AL = 00h if first FCB has valid drive letter, FFh if not AH = 00h if second FCB has valid drive letter, FFh if not [0] https://thestarman.pcministry.com/asm/debug/debug.htm#INIT https://thestarman.pcministry.com/asm/debug/debug.htm#INIT [1] http://www.delorie.com/djgpp/doc/rbinter/id/51/29.html http://www.delorie.com/djgpp/doc/rbinter/id/51/29.html
- boomlinde 8y agoThe value of BX is however strictly undefined, but practically always 0. Potentially some DOS will load this register with a different value, but probably no version of MS-DOS.
- freefal 8y agoBut why not explicitly set the register to 1 rather than assume its 0 and increment it by 1?
- boomlinde 8y agoSaves one byte, I assume. Register targets are typically encoded in the opcode while direct values follow the opcode byte.
- amenghra 8y agoOn x86, some instructions are longer than others. Incrementing is a single byte. Setting the value 1 if you don’t assume anything is going to be 2 bytes (al, ah, bl, etc.) or 4 bytes for (ax, bx, etc.) This online x86/x64 assembler is great: https://defuse.ca/online-x86-assembler.htm https://defuse.ca/online-x86-assembler.htm
- singularity2001 8y agocan I run this on linux? (wine?)
- basementcat 8y agoNot to poo-poo this (I think this is very impressive) but the reason why it is so small is that it just calls a bunch of bios and mouse driver routines. If those items didn’t already exist the program would surely be larger.
- EForEndeavour 8y agoExactly. Every language has its impressive one-liners and terse programs thanks to the underlying layers of abstraction, even asm.
- deleted 8y ago[deleted]
- prab97 8y ago"even ASM" - I read that twice to feel good.
- reaperducer 8y agoNot unique to Wintel, or this program. That's the reason programs were so small for the original Macintosh. Most of the essential routines, especially Quicktime, were in ROM.
- wrs 8y ago(I think you mean QuickDraw.) Yes, and the ROM itself was only 64kb of hand-written assembly, using a variety of techniques to cram in all that functionality, like sharing function prologues and epilogues.
- reaperducer 8y agoYep. QuickDraw. Been too long.
- userbinator 8y agoAll the program has to do is repeatedly get the current mouse position and set the pixel there, and that's all it does. These two links should help make sense of it: http://stanislavs.org/helppc/int_33.html http://stanislavs.org/helppc/int_33.html http://stanislavs.org/helppc/int_10.html http://stanislavs.org/helppc/int_10.html The main loop contains an implicit state-machine that does multiple things on different iterations, which is partly responsible for the small size. Another thing that you can clearly see is how efficient it is at using the registers; this is one area where compiler-generated code is consistently behind, and something I wish compilers would get better at --- an HLL could take as many bytes as this entire program just to put the parameters onto the stack and call a function. Finally, one small correction: ret ; assume [[FFEE]] = [0] = CD20 = int 20 ...should be "assume [FFFE] = 0", because that's where the stack pointer is initially, and this program does not use the stack itself for its entirety --- it doesn't need to!
- saagarjha 8y agoWhy is the ret necessary? Is this not an infinite loop?
- userbinator 8y agoThe loop instruction decrements CX, and then jumps if it is nonzero. Otherwise it "falls through". At that point CX contains the X coordinate of the cursor. Hence the comment: ; allows exit if the mouse is leftmost
- saagarjha 8y agoAh, I had zoomed in to see the code and completely disregarded the comments; in hindsight, I see that was a mistake. Although, I guess I should have guessed that cx could contain 0 in it.
- vectorEQ 8y agopretty cool, but why not have it a tiny tiny bit longer code and not strt with 2 flat out assumptions? I mean im not familiar with dos deeply and if these will be true 100% of the time, but as it reads, it reads like silly code which might crash or work unexpectedly in certain situations. either way cool! :D
- saagarjha 8y agoApparently these are a valid assumption to make in DOS.
- vectorEQ 8y agocool :) learning more about low level codes, and everyone tells me never to assume anything about a booting system ,but i suppose DOS will offer a more stable environment for programs to start then 'any x86_^64 hardware' :D thanks for clearing that up! it's a simple program but it sure shows that you can already do a lot with just a few bytes =]
- app4soft 8y agoSHPaint -- ANSI Art editor programmed in bash, written in 179 lines.[0,1] #!/bin/bash # # Author: Martin "BruXy" Bruchanov, bruxy at regnet.cz # # Check input first if [ ! $# -eq 1 ] || [ "$1" == "-h"] || [ "$1" == "--help" ] ; then printf "Usage:\n" printf "\t$0 saved_image\n" printf "\n\tImage data will be saved into given filename, if file exist\n" printf "\tit will be displayed and ready to edit!\n" printf "\tHit <Ctrl-C> any time to quit the program.\n" exit 1 fi ################## # Initialization # ################## IMAGE_FILE=$1 _STTY=$(stty -g) # Save current terminal setup printf "\e[2J" # clear screen, set cursos at beginning stty -echo -icanon # Turn off line buffering printf "\e[?9h" # Enable terminal mouse reading printf "\e[?25l" # Turn of cursor printf "\e]0;-=[ ShPaint ]=-\007" # Hash array with image data, # ... key is "$Y;$X", # ... value ANSI colors and brush "b;F;Bm" declare -A IMAGE # Defaults BRUSHES=( ) FG=( {30..37} ) BG=( {40..47} ) # 49 ... default background X=0 Y=0 ERASE=0 BRUSH=${BRUSHES[3]} FG_COLOR="1;${FG[7]}" BG_COLOR=49 ############# # Functions # ############# function save_image() { printf "\e[2J" > $IMAGE_FILE for i in ${!IMAGE[@]} do printf "\e[${i}f\e[${IMAGE[$i]}\e[0m" done >> $IMAGE_FILE # set cursor under the image printf "\e[$(tput lines);1f" >> $IMAGE_FILE } function at_exit() { printf "\e[?9l" # Turn off mouse reading printf "\e[?12l\e[?25h" # Turn on cursor stty "$_STTY" # reinitialize terminal settings clear echo "Thank for using ansipaint!" if [ ! -z "$IMAGE_FILE" ] ; then echo "Your image is saved as '$IMAGE_FILE'." save_image fi exit } # X = $1, Y = $2 function set_pos() { echo -en "\e[$2;$1f" } function show_pos() { set_pos 65 1 printf "x,y = %3d,%3d" $X $Y } function show_brush() { set_pos 70 2 printf "[ \e[${FG_COLOR};${BG_COLOR}m$BRUSH\e[0m ]" } function process_click() { # X=$1 Y=$2 # set foreground color if [ $Y -eq 1 ] || [ $Y -eq 2 ] ; then if [ $X -gt 2 ] && [ $X -lt 28 ] ; then FG_COLOR="$[Y-1];${FG[$[(X-4)/3]]}" ERASE=0 fi fi # set background color if [ $Y -eq 1 ] && [ $X -gt 34 ] ; then if [ $X -gt 34 ] && [ $X -lt 59 ] ; then BG_COLOR="${BG[$[X-35]/3]}" ERASE=0 else BG_COLOR="49" ERASE=0 fi fi # set brush if [ $Y -eq 2 ] && [ $X -gt 36 ] && [ $X -le 51 ] ; then BRUSH=${BRUSHES[$[(X-37)/2]]} ERASE=0 fi # set erase if [ $Y -eq 2 ] && [ $X -ge 54 ] && [ $X -le 62 ] ; then BRUSH=" " BG_COLOR="49" ERASE=1 fi # DEBUG # set_pos 0 25 # printf "$FG_COLOR $BG_COLOR $BRUSH" } function draw_menu() { set_pos 1 1; echo "FG: " for i in ${FG[*]} do set_pos $[(i-30)*3+4] 1 echo -en "\e[${i}m\e[0m" set_pos $[(i-30)*3+4] 2 echo -en "\e[1;${i}m\e[0m" done set_pos 30 1; echo "BG: " for i in ${BG[*]} do set_pos $[(i-40)*3+35] 1 echo -en "\e[${i}m \e[0m" done echo " |" # default background (49) set_pos 30 2; echo -en "Brush: ${BRUSHES[*]}" printf " [ Erase ]" show_brush } function load_image() { if [ -f $IMAGE_FILE ] ; then data=$(sed -e 's/\x1b/E/g;s/E\[0m/\n/g;s/E\[2J//' $IMAGE_FILE | \ sed -n -e 's/E\[\(.*\)fE\[\(.*m.\)/IMAGE["\1"]="\2"/ p') eval $data cat < $IMAGE_FILE fi } ########## # MAIN # ########## trap at_exit ERR EXIT load_image draw_menu while : do read -N 6 click mouse=( `echo -en ${click#???} | hexdump -v -e'1/1 " %u"'` ) X=$[ ${mouse[0]} - 32] Y=$[ ${mouse[1]} - 32] process_click show_pos show_brush if [ $Y -gt 2 ] ; then echo -en "\e[${Y};${X}f\e[${FG_COLOR};${BG_COLOR}m$BRUSH\e[0m" if [ $ERASE -eq 0 ] ; then IMAGE["${Y};${X}"]="${FG_COLOR};${BG_COLOR}m$BRUSH" else unset IMAGE["${Y};${X}"] fi fi done [0] http://bruxy.regnet.cz/web/linux/EN/ansi-art-sh-paint http://bruxy.regnet.cz/web/linux/EN/ansi-art-sh-paint [1] https://www.youtube.com/watch?v=aoAMxMukgPY https://www.youtube.com/watch?v=aoAMxMukgPY
- AstralStorm 8y agoSure, it's 12 lines of function calls to advanced DOS APIs and no actually useful functionality.
- jeffrallen 8y agoRight, but can it read email? https://en.wikipedia.org/wiki/Jamie_Zawinski#Principles https://en.wikipedia.org/wiki/Jamie_Zawinski#Principles