[Question]
  [
Inspired by this listing from the Commodore 64 User's Guide:
```
10 PRINT "{CLR/HOME}"
20 POKE 53280,7 : POKE 53281,13
30 X = 1 : Y = 1
40 DX = 1 : DY = 1
50 POKE 1024 + X + 40 * Y, 81
60 FOR T = 1 TO 10 : NEXT
70 POKE 1024 + X + 40 * Y, 32
80 X = X + DX
90 IF X <= 0 OR X >= 39 THEN DX = -DX
100 Y = Y + DY
110 IF Y <= 0 OR Y >= 24 THEN DY = -DY
120 GOTO 50
```
Make a similar program in your chosen language/platform to bounce a ball-alike object around your terminal, screen, canvas or other visual display area.
You don't have to mimic the C64's PETSCII graphics exactly, a simple `O` or `o` will do, nor do you have to use the `GOTO` command if it exists in your language still. As long as your ball starts at the top of your canvas and travels diagonally until it hits a canvas limit, and then bounces accordingly, as follows:
* Travelling downwards and right and hits the bottom of the screen area, bounces up and continues right;
* Travelling up and right and hits the right-most boundary, and bounces left and up;
* Travelling left and up and hits the top, bounces left and down;
* Travelling left and down and reaches the left-most boundary, bounces right and down;
* Hits any corner and reverses direction;
Then we're all good.
You don't have to move the ball 8-pixels at a time either, like is happening in the BASIC listing on the C64; you can move one character block or one pixel at a time, whichever you think is most appropriate.
To see this BASIC listing working, you can type it in with [this online Commodore 64 emulator](https://c64emulator.111mb.de/index.php?site=pp_javascript&lang=en&group=c64) providing your browser supports JavaScript.
  
[Answer]
# Bash + Unix utilities, ~~125~~ 117 bytes
```
for((x=y=u=v=1;;x+=u,y+=v,u=(x<1||x>=`tput cols`-1)?-u:u,v=(y<1||y>=`tput lines`-1)?-v:v)){
tput cup $y $x
sleep .1
}
```
---
Animation of sample run:
[![Animation of sample run](https://i.stack.imgur.com/0iZjQ.gif)](https://i.stack.imgur.com/0iZjQ.gif)
[Answer]
## [CP-1610](https://en.wikipedia.org/wiki/General_Instrument_CP1600) assembly, ~~67~~ … ~~64~~ 62 DECLEs = 78 bytes
This code is intended to be run on an [Intellivision](https://en.wikipedia.org/wiki/Intellivision). It's using one of its hardware sprites, known as a MOB (for Mobile Object).
A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This program is 62 DECLEs long, starting at $4800 and ending at $483D.
### Hexadecimal dump + source
```
                            ROMW  10            ; use 10-bit ROM
                            ORG   $4800         ; start program at address $4800
                    FRAME   EQU   $17E          ; frame #
                            ;; ------------------------------------------------ ;;
                            ;;  main entry point                                ;;
                            ;; ------------------------------------------------ ;;
                    main    PROC
4800 0001                   SDBD                ; load Interrupt Service Routine
4801 02B8 002B 0048         MVII  #isr,   R0    ; into R0
4804 0240 0100              MVO   R0,     $100  ; update ISR
4806 0040                   SWAP  R0
4807 0240 0101              MVO   R0,     $101
4809 02B9 0208              MVII  #$0208, R1    ; initialize R1 = X
480B 02BA 0108              MVII  #$0108, R2    ; initialize R2 = Y
480D 02BB 0001              MVII  #1,     R3    ; initialize R3 = DX
480F 009C                   MOVR  R3,     R4    ; initialize R4 = DY
4810 0002                   EIS                 ; enable interrupts
                            ;; ------------------------------------------------ ;;
                            ;;  main loop                                       ;;
                            ;; ------------------------------------------------ ;;
4811 0280 017E      @@loop  MVI   FRAME,  R0    ; R0 = current frame #
4813 0340 017E      @@spin  CMP   FRAME,  R0    ; wait for next frame
4815 0224 0003              BEQ   @@spin
4817 00D9                   ADDR  R3,     R1    ; X += DX
4818 0379 02A0              CMPI  #$2A0,  R1    ; reached right border?
481A 0204 0003              BEQ   @@updDx
481C 0379 0208              CMPI  #$208,  R1    ; reached left border?
481E 002F                   ADCR  PC
481F 0023           @@updDx NEGR  R3            ; DX = -DX
4820 00E2                   ADDR  R4,     R2    ; Y += DY
4821 037A 0160              CMPI  #$160,  R2    ; reached bottom border?
4823 0204 0003              BEQ   @@updDy
4825 037A 0108              CMPI  #$108,  R2    ; reached top border?
4827 002F                   ADCR  PC
4828 0024           @@updDy NEGR  R4            ; DY = -DY
4829 0220 0019              B     @@loop        ; loop forever
                            ENDP
                            ;; ------------------------------------------------ ;;
                            ;;  ISR                                             ;;
                            ;; ------------------------------------------------ ;;
                    isr     PROC
482B 01DB                   CLRR  R3            ; clear a bunch of STIC registers
482C 02BC 0020              MVII  #$20,   R4
482E 0263           @@clear MVO@  R3,     R4    ; (including background color,
482F 037C 0032              CMPI  #$32,   R4    ; border color, etc.)
4831 0226 0004              BLE   @@clear
4833 0259                   MVO@  R1,     R3    ; update X register of MOB #0
4834 0242 0008              MVO   R2,     $8    ; update Y register of MOB #0
4836 02BB 017E              MVII  #$017E, R3    ; update A register of MOB #0
4838 0243 0010              MVO   R3,     $10   ; (using a yellow "O")
483A 0298                   MVI@  R3,     R0    ; increment frame #
483B 0008                   INCR  R0
483C 0258                   MVO@  R0,     R3
483D 00AF                   JR    R5            ; return from ISR
                            ENDP
```
### Output
[![output](https://i.stack.imgur.com/S20vi.gif)](https://i.stack.imgur.com/S20vi.gif)
[Answer]
# TI-BASIC, ~~71~~ 70
```
1->A
1->B
1->C
1->D
While 1
ClrHome
Output(B,A,0
A+C->A
B+D->B
If A<2 or A>15
~C->C
If B<2 or B>7
~D->D
End
```
Quite literal translation, I wouldn't be surprised if there are tricks to make it smaller.
The screen is 16x8 and 1-indexed so the constants are different.
`~` is the SourceCoder way to write the negation symbol.
[![gif of bouncing O](https://i.stack.imgur.com/CcPtc.gif)](https://i.stack.imgur.com/CcPtc.gif)
It looks smoother on hardware.
[Answer]
# HTML (Microsoft Edge/Internet Explorer), 81 bytes
Pretend it's 1998 with these nested `<marquee>` tags:
```
<marquee behavior=alternate direction=down><marquee behavior=alternate width=99>O
```
Tested in Microsoft Edge, though from what I've read IE should also still support marquees. Decidedly does *not* work in Chrome.
Setting `direction=up` would save 2 bytes, but break the rule that the ball has to start at the top of the canvas.
[Answer]
# Befunge, 209 bytes
```
>10120130pppp>"l52?[J2["39*,,,,39*,,,,,,v
v+56/+55\%+55:+1g01*83-"6!"7\-"6!?"8-*86<
>00g1+:55+%\55+/"+!6"-48*,68>*#8+#6:#,_v$
v:+g03g01p02+-\g02*2!-*64\*2!:p00:+g02g<$
>10p:!2*\"O"-!2*30g\-+30p"2"::**>:#->#1_^
```
This assumes a screen size of 80x25, but you can easily tweak the range by replacing the `"O"` (79) on the last line and the `*64` (24) on the second last line (note that the second last line is executed right to left). The speed can also be adjusted by replacing the `"2"` (50) on the last line.
[Answer]
# Java, ~~184~~ 176 bytes
```
class A{public static void main(String[]a)throws Exception{for(int X=1,Y=1,x=1,y=1;;System.out.print("\033["+X+";"+Y+"H"),Thread.sleep(50),X+=x=X%25<1?-x:x,Y+=y=Y%85<1?-y:y);}}
```
This makes use of [ANSI Escape Sequences](http://ascii-table.com/ansi-escape-sequences.php) to relocate the cursor, which is the object that bounces around a `85 x 25` terminal display. Save in a file named `A.java`. 
## Ungolfed
```
class Terminal_Bouncing_Ball {
    public static void main(String[] args) throws InterruptedException {
        int X = 0, Y = 0, dx = 1, dy = 1;
        while (true) {
            System.out.print(String.format("\033[%d;%dH",X,Y));
            Thread.sleep(50);
            dx = (X < 1) ? 1 : (X > 71) ? -1 : dx;
            dy = (Y < 1) ? 1 : (Y > 237) ? -1 : dy;
            X += dx;
            Y += dy;
        }
    }
}
```
## Demo
[![Example](https://i.stack.imgur.com/BX36B.gif)](https://i.stack.imgur.com/BX36B.gif)
[Answer]
# [6502 machine code](https://en.wikibooks.org/wiki/6502_Assembly) (C64), 90 89 91 bytes
+2 bytes because it **needs** a load address (not PIC because of self modification)
```
00 C0 20 44 E5 CA D0 FD C6 FC D0 F9 A2 20 86 FC A9 D8 85 9E A9 03 85 9F A4 CA
18 A5 9E 69 28 85 9E 90 02 E6 9F 88 10 F2 A4 C9 8A 91 9E C9 20 D0 08 E6 C9 E6
CA A2 51 10 D7 A5 C9 F0 04 C9 27 D0 08 AD 2F C0 49 20 8D 2F C0 A5 CA F0 04 C9
18 D0 B4 AD 31 C0 49 20 8D 31 C0 D0 AA
```
**[Online demo](https://vice.janicek.co/c64/#%7B"controlPort2":"joystick","primaryControlPort":2,"keys":%7B"SPACE":"","RETURN":"","F1":"","F3":"","F5":"","F7":""%7D,"files":%7B"ball.prg":"data:;base64,AMAgROXK0P3G/ND5oiCG/KnYhZ6pA4WfpMoYpZ5pKIWekALmn4gQ8qTJipGeySDQCObJ5sqiURDXpcnwBMkn0AitL8BJII0vwKXK8ATJGNC0rTHASSCNMcDQqg=="%7D,"vice":%7B"-autostart":"ball.prg"%7D%7D)**
Usage: `sys49152`
I tried hard to reduce size (e.g. NOT using IRQs for timing but stupid empty loops instead), still impossible to reach the level of [Titus' golfed C64 BASIC](https://codegolf.stackexchange.com/a/110878/71420) :o oh, well. But it looks less flickering ;)
**Explanation:** (vice disassembly)
```
00 C0       .WORD $C000         ; load address
20 44 E5    JSR $E544           ; clear screen
CA          DEX
D0 FD       BNE $C003           ; inner wait (256 decrements)
C6 FC       DEC $FC
D0 F9       BNE $C003           ; outer wait (32 decrements in zeropage)
A2 20       LDX #$20            ; wait counter and screen code for "space"
86 FC       STX $FC             ; store wait counter
A9 D8       LDA #$D8            ; load screen base address ...
85 9E       STA $9E             ; ... -40 (quasi row "-1") ...
A9 03       LDA #$03            ; ... into vector at $9e/$9f
85 9F       STA $9F
A4 CA       LDY $CA             ; load current row in Y
18          CLC                 ; clear carry flag
A5 9E       LDA $9E             ; add ...
69 28       ADC #$28            ; ... $28 (40 cols) to ...
85 9E       STA $9E             ; ... vector
90 02       BCC $C023
E6 9F       INC $9F             ; handle carry
88          DEY                 ; count rows down
10 F2       BPL $C018
A4 C9       LDY $C9             ; load current col in Y
8A          TXA                 ; copy screen code from X to A
91 9E       STA ($9E),Y         ; store at position of screen
C9 20       CMP #$20            ; screen code was "space"
D0 08       BNE $C037           ; if not, ball was drawn
E6 C9       INC $C9             ; next column   | opcodes are modified
E6 CA       INC $CA             ; next row      | here for directions
A2 51       LDX #$51            ; screen code for "ball"
10 D7       BPL $C00E           ; and back to drawing code
A5 C9       LDA $C9             ; load current column
F0 04       BEQ $C03F           ; if zero, change X direction
C9 27       CMP #$27            ; compare with last column (39)
D0 08       BNE $C047           ; if not equal, don't change X direction
AD 2F C0    LDA $C02F           ; load opcode for X direction
49 20       EOR #$20            ; toggle between ZP INC and DEC
8D 2F C0    STA $C02F           ; store back
A5 CA       LDA $CA             ; load current row
F0 04       BEQ $C04F           ; if zero, change Y direction
C9 18       CMP #$18            ; compare with last row (24)
D0 B4       BNE $C003           ; if not equal, don't change Y direction
AD 31 C0    LDA $C031           ; load opcode for Y direction
49 20       EOR #$20            ; toggle between ZP INC and DEC
8D 31 C0    STA $C031           ; store back
D0 AA       BNE $C003           ; -> main loop
```
---
Just for fun, here's a more professional variant using a sprite for the ball and flashing the border when hit in **385** bytes (containing the sprite data that's used *in place*):
```
00 C0 AD 15 D0 F0 30 A9 CC 85 FC A9 04 20 A2 C0 A9 97 8D 00 DD A9 15 8D 18 D0 
A9 00 8D 15 D0 8D 1A D0 A2 81 8E 0D DC A2 31 8E 14 03 A2 EA 8E 15 03 58 A6 D6 
4C F0 E9 A9 04 85 FC A9 CC 20 A2 C0 A2 31 86 01 A2 10 A9 D0 85 FC B1 FB C6 01 
91 FB E6 01 C8 D0 F5 E6 FC CA D0 F0 A9 37 85 01 A9 94 8D 00 DD A9 35 8D 18 D0 
8D 27 D0 A2 05 8E F8 CF A2 01 8E 15 D0 8E 1A D0 8E 12 D0 86 FD 86 FE A2 18 8E 
00 D0 A2 1B 8E 11 D0 A2 32 8E 01 D0 A2 7F 8E 0D DC AE 0D DC AE 20 D0 86 FB A2 
C1 8E 14 03 A2 C0 D0 8A 85 FE 8D 88 02 A9 00 85 FB 85 FD A2 04 A0 00 78 B1 FB 
91 FD C8 D0 F9 E6 FC E6 FE CA D0 F2 60 A6 FB 8E 20 D0 CE 19 D0 A5 FD F0 20 AD 
00 D0 18 69 04 8D 00 D0 90 03 EE 10 D0 C9 40 D0 2C AD 10 D0 29 01 F0 25 20 38 
C1 C6 FD F0 1E AD 00 D0 38 E9 04 8D 00 D0 B0 03 CE 10 D0 C9 18 D0 0C AD 10 D0 
29 01 D0 05 20 38 C1 E6 FD A5 FE F0 14 AD 01 D0 18 69 04 8D 01 D0 C9 E6 D0 19 
20 38 C1 C6 FE F0 12 AD 01 D0 38 E9 04 8D 01 D0 C9 32 D0 05 20 38 C1 E6 FE 4C 
31 EA A9 01 8D 20 D0 60 00 00 00 7E 00 03 FF C0 07 FF E0 1F FF F8 1F FF F8 3F 
FF FC 7F FF FE 7F FF FE FF FF FF FF FF FF FF FF FF FF FF FF 7F FF FE 7F FF FE 
3F FF FC 1F FF F8 1F FF F8 07 FF E0 03 FF C0 00 7E 00 00 00 00 
```
**[Online demo](https://vice.janicek.co/c64/#%7B"controlPort2":"joystick","primaryControlPort":2,"keys":%7B"SPACE":"","RETURN":"","F1":"","F3":"","F5":"","F7":""%7D,"files":%7B"spball.prg":"data:;base64,AMCtFdDwMKnMhfypBCCiwKmXjQDdqRWNGNCpAI0V0I0a0KKBjg3cojGOFAOi6o4VA1im1kzw6akEhfypzCCiwKIxhgGiEKnQhfyx+8YBkfvmAcjQ9eb8ytDwqTeFAamUjQDdqTWNGNCNJ9CiBY74z6IBjhXQjhrQjhLQhv2G/qIYjgDQohuOEdCiMo4B0KJ/jg3crg3criDQhvuiwY4UA6LA0IqF/o2IAqkAhfuF/aIEoAB4sfuR/cjQ+eb85v7K0PJgpvuOINDOGdCl/fAgrQDQGGkEjQDQkAPuENDJQNAsrRDQKQHwJSA4wcb98B6tANA46QSNANCwA84Q0MkY0AytENApAdAFIDjB5v2l/vAUrQHQGGkEjQHQyebQGSA4wcb+8BKtAdA46QSNAdDJMtAFIDjB5v5MMeqpAY0g0GAAAAB+AAP/wAf/4B//+B//+D///H///n///v///////////////3///n///j///B//+B//+Af/4AP/wAB+AAAAAA=="%7D,"vice":%7B"-autostart":"spball.prg"%7D%7D)** -|- **[browse ca65 assembler source](https://github.com/Zirias/c64spball)**
Start and stop the bouncing ball with `sys49152`.
* This leaves the C64 BASIC running, that's done by moving the VIC-II address space up to `$C000`, which requires copying the screen contents and the character set (font).
* It hooks into the system IRQ and to avoid flicker, changes the source of this IRQ to the VIC-II graphics chip, so updates are always done between frames.
* Glitches:
	1. `RUN/STOP + RESTORE` is broken, don't try.
	2. With the VIC-II as IRQ source, the cursor blinks slightly slower and `TI$` will lag behind as well.
	3. when stopping while the border is flashed (very unlikely but possible), it **stays** white -- you have to restore it manually.
[Answer]
# Clojure, ~~398~~ ~~380~~ 375 bytes
```
(ns g(:require[quil.core :as q]))(def w 1e3)(def h 1e3)(def f 100)(def b(atom{:x f :y f :n 1 :m 1}))(q/defsketch . :size[w h]:setup #(do(q/text-font(q/create-font""f))(q/fill 255 255 255)):draw #(let[s 9{x :x y :y n :n m :m}@b c(+ x(* n s))u(+ y(* m s))](q/background 0 0 0)(reset! b{:x c :y u :n(if(< 0 c(- w f))n(* -1 n)):m(if(<(+ 0 f)u h)m(* -1 m))})(q/text"O"(:x @b)(:y @b))))
```
-18 bytes by changing the font name to an empty string to default it, inlining the boundary checks, and fixing the bottom boundary issue (which you can see in the GIF). Fixing that actually saved bytes.
-5 bytes by changing to a more succinct destructuring syntax and shrinking the ball by a pixel.
Uses [Quil](http://quil.info/).
I tried to switch to functional mode, but it required a lot of extra code and ended up being more expensive.
```
(ns bits.golf.ball-bounce
  (:require [quil.core :as q]))
(def width 1000)
(def height 1000)
(def font-size 100)
; Mutable state holding the properties of the ball. n and m are the directions on the x and y axis.
(def ball (atom {:x 300 :y 600 :n 1 :m 1}))
(q/defsketch b
  :size [width height] ; Window size
  :setup #(do
            (q/text-font (q/create-font "Arial" font-size)) ; Set the font
            (q/fill 255 255 255)) ; And the text color
  :draw
  #(let [speed 9
         ; Deconstruct the state
         {:keys [x y n m]} @ball
         next-x (+ x (* n speed))
         next-y (+ y (* m speed))
         ; I'm adding/subtracting the font-size so it stays in the window properly
         x-inbounds? (< 0 next-x (- width font-size))
         y-inbounds? (< (+ 0 font-size) next-y height)]
     ; Wipe the screen so the ball doesn't smear
     (q/background 0 0 0)
     ; Reset the state
     (reset! ball
             {:x next-x
              :y next-y
              :n (if x-inbounds? n (* -1 n))
              :m (if y-inbounds? m (* -1 m))})
     ; Draw the ball
     (q/text "O" (:x @ball) (:y @ball))))
```
[![Ball Bouncing GIF](https://i.stack.imgur.com/nM7nb.gif)](https://i.stack.imgur.com/nM7nb.gif)
(Note, the new version doesn't bounce early along the bottom of the screen like it does in the GIF.)
[Answer]
## Racket 247 bytes
```
(let*((w 500)(h(* w 0.6))(x 100)(y 0)(d 10)(e d)(G(λ(t)(set! x(+ x d))(when(or(> x w)(< x 0))
(set! d(* d -1)))(set! y(+ y e))(when(or(> y h)(< y 0))(set! e(* e -1)))
(underlay/xy(rectangle w h"solid""white")x y(circle 10"solid""black")))))(animate G))
```
Ungolfed: 
```
(require 2htdp/image
         2htdp/universe) 
(let* ((wd 500)            ; define variables and their initial values
       (ht 300)
       (x 100)
       (y 0)
       (dx 10)
       (dy 10)
       (imgfn              ; define function to draw one frame; called repeatedly by animate fn; 
        (λ (t)             ; t is number of ticks till now- sent by animate fn; ignored here;
                           ; update location (x and y values):
          (set! x (+ x dx))
          (when (or (> x wd) (< x 0))
            (set! dx (* dx -1)))             ; invert direction at edges
          (set! y (+ y dy))
          (when (or (> y ht) (< y 0))
            (set! dy (* dy -1)))             ; invert direction at edges
                           ; draw image: 
          (underlay/xy
           (rectangle wd ht "solid" "white") ; draw background
           x y                               ; go to location (x,y)
           (circle 10 "solid" "black")       ; draw ball
          ))))
  (animate imgfn))         ; animates the images created by imgfn (default rate 28 times/sec)
```
Output: 
[![enter image description here](https://i.stack.imgur.com/UNdnr.gif)](https://i.stack.imgur.com/UNdnr.gif)
[Answer]
# Simons´ BASIC (C64), ~~66~~ 65 bytes
One byte saved thanks @ShaunBebbers.
I need only one line here, because Simons´ Basic has a modulo function.  
AfaIk, this requires a physical C64 and a Simons´ BASIC module  
(or any other BASIC extension that has a `mod` function).
```
0fori=0to623:print"{CLR}":poke1024+40*abs(mod(i,48)-24)+abs(mod(i,78)-39),81:next:goto
```
Type in these 69 characters:
```
0fOi=0TO623:?"{CLR}":pO1024+40*aB(mod(i,48)-24)+aB(mod(i,78)-39),81:nE:gO
```
`{CLR}` is [PETSCII](https://dflund.se/%7Etriad/krad/recode/pet2.jpg) 147, which clears the screen. Use Shift+CLR/HOME to type it in.
**bytecount**
When saved to disk, it takes 65 bytes, because the commands are tokenized:  
`for`, `to`, `poke`, `abs`, `next` and `goto` are one byte each; `mod` takes two bytes.  
That makes 59 bytes of code plus 4 bytes for pointers and 2 bytes for the line number.
For reference, see [Mapping the C64](http://www.unusedino.de/ec64/technical/project64/mapping_c64.html) and search for `$800` (BASIC Program Text).  
(You can find the Video Screen Memory Area at `$400`.)
**breakdown**
The program loops `I` from 0 to 623 (=LCM of 48 and 78 minus 1). In the loop
* the screen is cleared
* `I` gets mapped to 39..0..38 respectively 24..0..23
* and the blob (PETSCII 81) is put at the corresponding position in the video memory  
(like the original program does).
When the loop is done, the program is restarted by jumping to line 0.
# C64 BASIC, ~~77~~ 76 bytes
```
0fori=0to623:print"{CLR}"
1poke1024+40*abs(i-48*int(i/48)-24)+abs(i-78*int(i/78)-39),81:next:goto
```
---
Unfortunately I need two lines, because even with all possible abbreviations it would take 83 characters - too many to use the C64 line editor:
```
0fOi=0to623:?"{CLR}":pO1024+40*aB(i-48*int(i/48)-24)+aB(i-78*int(i/78)-39),81:nE:gO
```
(A hex editor could be used to create a longer line - which would make it 73 bytes.)
[Answer]
# Jelly, 37 bytes
```
“ñc‘Ọ24ḶŒḄṖ⁸ị⁷x⁸µ80ḶŒḄṖ⁸ị⁶x⁸‘œS.1
Ç1¿
```
With some help from [this answer](https://codegolf.stackexchange.com/a/110480/63647) for getting the loop and escape characters right. Currently it bounces around in a 80x24 screen, but that can be easily modified in the code.
The coördinates in each direction can be represented as elements of two lists `[0, 1,..., 24, 23,..., 1]` and `[0, 1,..., 80, 79,..., 1]`, let's call them `Y` and `X`, that are infinitely repeated. This infinite repetition can be emulated using modular indexing -- using `ị` in Jelly. Example: in the `i`th iteration the ball is at position `(X[i%|X|], Y[i%|Y|]) = (iịY, iịX)`. The moving *ball* is just the cursor that is put into position by emitting `iịY` newlines and `iịX` spaces.
## Demo
[![https://i.gyazo.com/b8eac64097cb6d3a18185877c2f4c945.gif](https://i.stack.imgur.com/5bsw3.gif)](https://i.stack.imgur.com/5bsw3.gif)
## Explanation
```
“ñc‘Ọ24ḶŒḄṖ⁸ị⁷x⁸µ80ḶŒḄṖ⁸ị⁶x⁸‘œS.1        Monadic helper link - argument i.
                                         Resets the terminal, prints Y[i] newlines,
                                         X[i] spaces and returns i + 1.
“ñc‘                                     Set the output to [27, 99]
    Ọ                                    Convert to characters and print (\x1bc)
                                          -> Cursor is at position (0,0)
     24Ḷ                                 Lowered range of 24. Yields [0,...,23].
        ŒḄ                               Bounce. Yields [0,...,23,22,...,0].
          Ṗ                              Pop. Yields [0,...,23,22,...,1] = Y.
           ⁸ị                            Modular index i (⁸) into Y. The current
                                         value is the Y coordinate, y.
              x                          Repeat y times
             ⁷                           the newline character ('\n').
               ⁸                         Output that (y times '\n') and continue
                                         with value i.
                                          -> Cursor is at position (0, y)
                µ                        Monadic chain separation.
                 80ḶŒḄṖ                  Same as above, but this time yielding X.
                       ⁸ị                Modular index i into X, yielding the
                                         value for x.
                          x              Repeat x times
                         ⁶               the whitespace character.
                           ⁸             Output that (x times ' ') and continue
                                         with value i.
                                         -> Cursor is at position (x, y), the
                                            final position.
                             œS.1        Wait 0.1 seconds.
                            ‘            Return i + 1.
Ç1¿                                      Main (niladic) link.
 1¿                                      While true.
Ç                                        Call the helper link. The first time
                                         there is no argument and i will be [],
                                         which is cast to 0 when used as integer
                                         (e.g. try ‘¶Ç). After that, the previous
                                         return value (i + 1) is used.
```
[Answer]
# SmileBASIC, ~~85~~ 74 bytes
```
SPSET.,9M=MAINCNT
SPOFS.,ASIN(SIN(M/5))*122+192,112+71*ASIN(SIN(M/3))EXEC.
```
The position of the ball can be modelled with 2 triangle waves, and the shortest way I could find to produce them in SmileBASIC was arcsine(sine(x)). (the algorithm using MOD was longer since SB uses `MOD` instead of `%`)
[Answer]
## CSS/HTML, 200 + 7 = 207 bytes
```
p{position:relative}a{position:absolute;animation:infinite linear alternate;animation-name:x,y;animation-duration:7.9s,2.3s}@keyframes x{from{left:0}to{left:79ch}}@keyframes y{from{top:0}to{top:24em}}
```
```
<p><a>O
```
This version shows you the size of the canvas and also gives the animation a more pixilated feel:
```
p {
  position: relative;
  width: 80ch;
  height: 25em;
  border: 1px solid black;
}
a {
  position: absolute;
  animation: infinite alternate;
  animation-name: x, y;
  animation-duration: 7.9s, 2.3s;
  animation-timing-function: steps(79), steps(23);
}
@keyframes x {
  from {
    left: 0;
  } to {
    left: 79ch;
  }
}
@keyframes y {
  from {
    top: 0;
  } to {
    top: 24em;
  }
}
```
```
<p><a>O</a></p>
```
[Answer]
# Dyalog APL, 44 bytes
```
{⎕SM∘←0,G←⍺+⍵⋄G∇⍵×1-2×⊃1 G∨.≥G⎕SD⊣⎕DL.1}⍨1 1
```
Explanation:
* `{`...`}⍨1 1`: call the given function with ⍺=⍵=1 1
	+ `⎕SM∘←0,G←⍺+⍵`: store `⍺+⍵` in `G`, display a `0` at that location in the `⎕SM` window.
	+ `⎕DL.1`: wait 1/10th of a second
	+ `⊃1 G∨.≥G⎕SD`: check if `G` is at the `⎕SM` window boundary (`1≥G` or `G≥⎕SD`, `⎕SD` is the **s**creen **d**imensions)
	+ `1-2×`: map `[1,0]` onto `[¯1,1]`, to flip the direction of travel
	+ `⍵×`: multiply the current direction of travel by that
	+ `G∇`: recursion, let `G` be the new location (`⍺`) and `⍵....` be the new direction (`⍵`).
[Answer]
# PHP, ~~112~~ ~~97~~ ~~94~~ ~~103~~ 102 bytes
```
for(;;usleep(1e5),$i%=624)echo($r=str_repeat)(A^K,99),$r(A^a,abs($i%78-39)),O,$r(A^K,abs($i++%48-24));
```
bounces a capital `O` on a 40x25 grid, starting at the top right corner;  
prints 99 newlines to clear the screen.
Run with `-nr`.
`A^K` = `chr(10)` = newline  
`A^a` = `chr(32)` = space
[Answer]
# C + curses, 190 bytes
```
#include<curses.h>
w;h;x;y;d;main(e){initscr();curs_set(0);getmaxyx(stdscr,h,w);for(d=e;;usleep(20000),mvaddch(y,x,32)){mvaddch(y+=d,x+=e,48);if(!y||y>h-2)d=-d;if(!x||x>w-2)e=-e;refresh();}}
```
**Explanation:**
```
#include<curses.h>
w;h;x;y;d;
main(e)
{
    initscr();
    curs_set(0);
    getmaxyx(stdscr,h,w);
    // initialize distances to 1 (e is 1 when called without arguments)
    // wait for 1/5 second, then write space character at current pos
    for(d=e;;usleep(20000),mvaddch(y,x,32))
    {
        // advance current pos and write ball character (`0`)
        mvaddch(y+=d,x+=e,48);
        // check and change direction:
        if(!y||y>h-2)d=-d;
        if(!x||x>w-2)e=-e;
        // trigger output to screen:
        refresh();
    }
}
```
[Answer]
# [QBasic](https://en.wikipedia.org/wiki/QBasic), 71 bytes
```
DO
CLS
LOCATE 24-ABS(i MOD 46-23),80-ABS(i MOD 158-79)
?"O";
i=i+1
LOOP
```
This version loops forever, although it might break when `i` gets too large--I haven't tested. Also, how fast it moves depends on the hardware you use, but on the emulator at [Archive.org](https://archive.org/details/msdos_qbasic_megapack) it runs too fast to see the motion. Therefore, here's a somewhat friendlier version that terminates once the ball gets back to the top left corner:
```
FOR i=0TO 3634
CLS
LOCATE 24-ABS(i MOD 46-23),80-ABS(i MOD 158-79)
?"O";
z=COS(1)
NEXT
```
Change the `COS(1)` to `COS(1)+COS(1)+COS(1)` (etc.) to slow it down further. [Try it here!](https://archive.org/details/msdos_qbasic_megapack)
### Explanation
Our bounding box is QBasic's standard text mode screen, 80 characters wide by 24 characters tall, 1-indexed. As several other answers have observed, we can calculate the correct x and y coordinates, given a frame number, using modular arithmetic:
| Frame `i` | `i MOD 46` | `(i MOD 46)-23` | `ABS((i MOD 46)-23)` | y = `24-ABS(...)` | x = `80-ABS(...)` |
| --- | --- | --- | --- | --- | --- |
| 0 | 0 | -23 | 23 | 1 | 1 |
| 1 | 1 | -22 | 22 | 2 | 2 |
| 22 | 22 | -1 | 1 | 23 | 23 |
| 23 | 23 | 0 | 0 | 24 | 24 |
| 24 | 24 | 1 | 1 | 23 | 25 |
| 45 | 45 | 22 | 22 | 2 | 46 |
| 46 | 0 | -23 | 23 | 1 | 47 |
| 47 | 1 | -22 | 22 | 2 | 48 |
| 79 | 33 | 10 | 10 | 14 | 80 |
| 80 | 34 | 11 | 11 | 13 | 79 |
After that it's just an issue of clearing the screen with `CLS`, moving to the proper coordinates with `LOCATE`, and printing `"O"`.
[Answer]
# Python 2, ~~176~~ 168 Bytes
This assumes a terminal size of 80x24. Definitely not optimal but I'm new to golfing so yeah.
```
import time;x=y=d=e=1
while 1:
 m=[[' 'for i in' '*80]for j in' '*24];x+=d;y+=e;m[y][x]='O';time.sleep(.1)
 if x%79<1:d=-d
 if y%23<1:e=-e 
 for r in m:print''.join(r)
```
Thanks to R. Kap for suggesting the x%79<1 instead of x<1or x>79 and ditto for y.
[Answer]
# Rebol/View, 284 266 bytes
```
rebol[]p: 3x9 d:[3 3]view layout[b: box blue 99x99 effect[draw[circle p 2]]rate :0.01 feel[engage: func[f a e][if a = 'time[case/all[p/x < 2[d/1: abs d/1]p/y < 2[d/2: abs d/2]p/x > 98[d/1: negate d/1]p/y > 98[d/2: negate d/2]]p/x: p/x + d/1 p/y: p/y + d/2 show b]]]]
```
Ungolfed:
```
rebol []
p: 3x9     ;; starting position
d: [3 3]   ;; direction
view layout [
    b: box blue 99x99 effect [
        draw [
            circle p 2
        ]
    ]
    rate :0.01 feel [
        engage: func [f a e] [
            if a = 'time [
                case/all [
                    p/x < 2  [d/1: abs d/1]
                    p/y < 2  [d/2: abs d/2]
                    p/x > 98 [d/1: negate d/1]
                    p/y > 98 [d/2: negate d/2]
                ]
                p/x: p/x + d/1
                p/y: p/y + d/2
                show b
            ]
        ]
    ]
]
```
[Answer]
## C 294 bytes
```
#include<graphics.h> f(){int d=0;g,x,y,a=0,b=0;initgraph(&d,&g,NULL);x=30;y=30;while(1){x+=6;y+=7;if(y<60)b=0;if(x<60)a=0;if((y>getmaxy()-40)) b=!b;if((x>getmaxx()-40))a=!a;if(b){y-=18;x+=3;}if(a){x-=15;y+=2;}usleep(10000);setcolor(4);cleardevice();circle(x, y,30);floodfill(x,y,4);delay(45);}}
```
Ungolfed version:
```
#include<graphics.h>
void f()
{
 int d=DETECT,g,x,y,r=30,a=0,b=0;
 initgraph(&d,&g,NULL);
 x=30;
 y=30;
 while(1)
 {
   x+=6;
   y+=7;
   if(y<60)
     b=0;
   if(x<60)
     a=0;     
   if((y>getmaxy()-40))
        b=!b;
   if((x>getmaxx()-40))
        a=!a;
    if(b)
    {       
        y-=18;
        x+=3;
    }
    if(a)
    {       
       x-=15;
       y+=2;               
    } 
    usleep(10000);
    setcolor(RED);
    cleardevice();
    circle(x,y,r);
    floodfill(x,y,RED);
    delay(45);
  }   
}
```
## Explanation
* So in order to begin with this, I had to get `graphics.h` in my `/usr/include` directory. Therefore, i searched and [this](https://askubuntu.com/questions/525051/how-do-i-use-graphics-h-in-ubuntu) is what I found. It is a TurboC Graphics implementation using SDL for Linux. One could also use OpenGL. In windows, I guess it is already installed, not sure about MacOS.
* `void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);` initialises the system and puts it in a graphics mode, in this case graphics driver is automatically detected. Please refer to this [link](https://www.cs.colorado.edu/~main/bgi/doc/initgraph.html) for more details.
* `x` and `y` are coordinates that determines the ball's position.
* `a` and `b` are flags, `a` is set to zero when the `x` value drops below 60 and `b` is set to zero when `y` drops below 60.
* The flags are toggled when `x` and `y` exceeds boundary values of window, and the coordinates are accordingly adjusted.
* I put a `usleep` so that my CPU does not get stressed out.
* One should normally use a `closegraph()` call, in order to close the window. But it's missing here.
Must be compiled with the linker flag `-lgraph`
It runs smoother on real hardware. :)
[![Bouncing Red Ball](https://i.stack.imgur.com/ZbXAV.gif)](https://i.stack.imgur.com/ZbXAV.gif)
[Answer]
# [MATL](https://github.com/lmendo/MATL), 42 bytes
```
1thXH_XI`Xx8E70hZ"79HZ}&(DH4M\1>EqI*XIH+XH
```
This uses a 70×16 screen and character `O`. If you wait for a few bounces you'll see the ball hitting a corner.
[**Try at MATL Online!**](https://matl.suever.net/?code=1thXH_XI%60Xx8E70hZ%2279HZ%7D%26%28DH4M%5C1%3EEqI%2aXIH%2BXH&inputs=&version=19.8.0)
Screen size can be easily modified in the code. The relevant part is `8E70`, which pushes `8`, doubles it, and pushes `70`. For example, for a 80×25 screen replace by `5W80`, which pushes `5`, squares it, and pushes `80` (or replace by `25 80`, but that requires one more byte).
Also, adding `tD` at the end of the code shows the current position in real time (vertical, then horizontal, `1 1` is upper left). As an example, for a `80×18` screen,
```
1thXH_XI`Xx9E80hZ"79HZ}&(DH4M\1>EqI*XIH+XHtD
```
[**Try it too!**](https://matl.suever.net/?code=1thXH_XI%60Xx9E80hZ%2279HZ%7D%26%28DH4M%5C1%3EEqI%2aXIH%2BXHtD&inputs=&version=19.8.0)
### Explanation
This uses an infinite loop. Position is kept in clipboard `H` as a 1×2 vector, and direction is kept in clipboard `I` as a 1×2 vector with entries `1` or `-1`.
Each iteration clears the screen, defines a matrix of spaces, writes an `O` at the relevant position, and displays it. Then the position and directio need to be updated.
Position is `1`-based, and thus the edges of the screen are `1` and the maximum screen size. So if position modulo screen size gives `0` or `1` in either the first or second components, which means we have reached a vertical or horizontal edge respectively, that component of the direction vector is negated. After that, the new direction is added to the current position to obtain the new position.
[Answer]
Here's the ZX Spectrum listing.
```
  10 FOR n=0 to 7
  20 READ a: POKE USR "a"+n, a
  30 NEXT n
  40 DATA 60,126,243,251,255,255,126,60
  50 LET x=10:LET y=10:LET vx=1: LET vy=1
  60 PRINT AT y,x;"\a"
  70 IF x<1 OR x>30 THEN LET vx=-vx
  80 IF y<1 OR x>20 THEN LET vy=-vy
  90 LET x=x+vx: LET y=y+vy
 100 PRINT AT y-vy,x-vx;" ": GO TO 60
```
[Answer]
# [Lua](https://en.wikipedia.org/wiki/Lua_(programming_language)) ([LÖVE 2D](https://love2d.org/)), 130 bytes
```
x,y,a,b=0,0,1,1
function love.draw()a=(x<0 or x>800)and-a or a
b=(y<0 or y>600)and-b or b
x=x+a
y=y+b
love.graphics.points(x,y)end
```
Lua is not the best language when it comes to code golf, but here you go! A few points worth mentioning:
* The default canvas size is 800 x 600. It can be changed in the configuration file, but I didn't see any size restrictions, so I left it as is.
* [`love.draw()`](https://love2d.org/wiki/love.draw) is LÖVE's drawing function and it has a predetermined name. Alternative LÖVE functions that could be used would be [`love.update(dt)`](https://love2d.org/wiki/love.update) and [`love.run()`](https://love2d.org/wiki/love.run) -- the first being longer, in bytes, and the latter being shorter, yes, but without a built-in infinite loop. Thus, `draw()` seems to be our best bet here.
* The above version uses [`love.graphics.points`](https://love2d.org/wiki/love.graphics.points) to draw the ball. Although shorter, I am not sure it is allowed. Here is a GIF of how it runs:
[![Animated screenshot - point](https://i.stack.imgur.com/yW6aL.gif)](https://i.stack.imgur.com/yW6aL.gif)
As you can see (or perhaps can't), there is a single pixel moving on the screen. While that saves up bytes, it's not the most satisfying of results.
So I've made an **alternative 131 bytes solution**:
```
x,y,a,b=0,0,1,1
function love.draw()a=(x<0 or x>795)and-a or a
b=(y<0 or y>595)and-b or b
x=x+a
y=y+b
love.graphics.print(0,x,y)end
```
This one uses [`love.graphics.print`](https://love2d.org/wiki/love.graphics.print) -- which prints text -- and a `0` as a ball, making it much more visible and appealing.
[![Animated screenshot - zero](https://i.stack.imgur.com/MFG7s.gif)](https://i.stack.imgur.com/MFG7s.gif)
[Answer]
# CHIP-8, ~~36~~ ~~34~~ 28 bytes
```
FF29 'LDF I,vF //load digit sprite for the value of vF (should be 0)
4000 'SNE v0,0 //if x is 0...
6201 'LD v2,1 //set x velocity to 1
403C 'SNE v0,3C //if x is 3C...
62FF 'LD v2,FF //set x velocity to -1
4100 'SNE v1,0 //if y is 0...
6301 'LD v3,1 //set y velocity to 1
411B 'SNE v1,1B //if y is 1B...
63FF 'LD v3,FF //set y velocity to -1
D015 'DRW v0,v1,5 //draw sprite
D015 'DRW v0,v1,5 //draw sprite again to clear it.
8024 'ADD v0,v2 //add x velocity to x
8134 'ADD v1,v3 //add y velocity to y
1202 'JMP 202 //jump to second instruction
```
No fancy tricks here...
Requires an interpreter that draws sprites correctly (only one sprite can be drawn per frame, which slows down the program enough for you to be able to see it).
[Low quality video](https://www.youtube.com/watch?v=jJpk0vTjhss)
[Answer]
## PostScript (GhostScript), 259 bytes
I don't think PostScript was built for animation... improvements welcome!
```
[/x{4}/y{196}/X{2}/Y{-2}/b{x y 4 currentgray add 0 360 arc fill}/p{/x x X add def}/q{/y y Y add def}/g{setgray}>>begin[/PageSize[320 200]>>setpagedevice{1 g
b p q
x 316 gt x 4 lt or{/X X -1 mul def}if
y 196 gt y 4 lt or{/Y Y -1 mul def}if
0 g b flushpage}loop
```
Needs GhostScript for `flushpage`.
[![animation](https://i.stack.imgur.com/1cSNe.gif)](https://i.stack.imgur.com/1cSNe.gif)
(It runs smoother when the screen recorder isn't also running.)
[Answer]
# Commodore C64 BASIC - 75 71 tokenised BASIC bytes, 77 73 characters with keyword abbreviations
The following answer is taken from the YouTube channel [8-BIT Show and Tell](https://youtu.be/jhQgHW2VI0o "8-BIT Show and Tell, One-Line Bouncing Ball: Commodore 64 BASIC"), so Robin Harbron deserves the credit, along with credit to the YouTube channel [JosipRetroBits](https://www.youtube.com/@JosipRetroBits).
```
 0?"{CLEAR}":DEFFNA(B)=ABS(T-INT(T/B)*B-B/2):POKE1024+FNA(48)*40+FNA(78),81:T=T+1:GOTO
```
### Older solution
```
 0?"{CLEAR}":DEFFNA(B)=ABS(T-INT(T/B)*B-B/2):Z=1024+FNA(48)*40+FNA(78):POKEZ,81:T=T+1:GOTO
```
The listing is above one logical (Commodore C64) line in Commodore BASIC, so it must be typed with keyword abbreviations, as in the screen shot below.
A full explanation of what is going on is linked above.
[![Commodore C64 BASIC Bouncing Ball](https://i.stack.imgur.com/lhHlY.png)](https://i.stack.imgur.com/lhHlY.png)
[Answer]
# ZX Spectrum BASIC - 179 bytes
Here it is just condensed a little bit. It's 179 bytes with the ball graphics included
```
  10 LET a=10: LET b=10: LET c=1: LET d=-1: FOR e=0 TO 7: READ f: POKE USR "a"+e, f: NEXT e
  20 DATA 60, 126,243,251,255,255,126,60
  30 PRINT AT b,a;"\a"
  40 IF a<1 OR a>30 THEN LET c=-c
  50 IF b<1 OR b>20 THEN LET d=-d
  60 LET a=a+c: LET b=b+d: PRINT AT b-d, a-c;" ": GO TO 30
```
]