Use EDIT to edit the currently loaded (or new) BASIC LISTing.

Use XLIST to display a colourised, organised BASIC LISTing in a text viewer.

The following “at” (@) functions may be used inside microM8’s enhanced Applesoft (“Floating Point”) and Integer BASIC interpreters. These functions add graphics, sound and other capabilities not available in the original interpreters while maintaining compatibility with existing Applesoft and Integer BASIC programs.

If you can think of any other potential functions, please let us know!

@asm.build{input: STRING, output: STRING, cpu: STRING}

Assemble file “input” to “output”, using optional cpu type “6502”, “65C02”.  If output is blank, assemble to memory.

@audio.pause{}

Pause audio stream.

@audio.play{file: STRING, block: NUMBER}

Play a short audio file.

@audio.resume{}

Resume a paused audio file.

@audio.stop{}

Stop a playing audio file.

@audio.stream{file: STRING, leadin: NUMBER, fadein: NUMBER}

Play an audio stream “file” with optional “leadin” (silence), and “fadein”.

@backdrop.camtrack{camtrack: NUMBER}

Causes a backdrop to move with the camera at a specific ratio provided by NUMBER.

@backdrop.filename{image: STRING}

Set backdrop to “image”.  If image is “”, clear backdrop.

@backdrop.move{x: NUMBER, y: NUMBER, z: NUMBER}

Move backdrop (relatively) in 3D space by “x”, “y”, “z”.

@backdrop.opacity{opacity: NUMBER}

Set backdrop “opacity” between 0 (full transparent) and 1 (solid). 

@backdrop.pos{x: NUMBER, y: NUMBER, z: NUMBER}

Set backdrop position (absolute).

@backdrop.reset{}

Clear and reset backdrop settings.

@backdrop.zoom{zoom: NUMBER}

Set backdrop zoom level to “zoom” (16 default).

@backdrop.zrat{zoomf: NUMBER}

Set zoom ratio (amount zoom changes) based on camera zoom to “zoomf”.

@bug.close{id: NUMBER, comment: STRING}

Close bug “id” with comment “comment”.

@bug.comment{id: NUMBER, comment: STRING}

Add a comment “comment” to a bug “id”.

@bug.create{summary: STRING, body: STRING, capture: NUMBER}

Log a new bug with summary “summary”, and body “body”.  If capture is “1”, attach memory.

@bug.list{}

List all open bugs.

@bug.load{id: NUMBER}

Load a bug with id “id”.

@bug.show{id: NUMBER}

Show a bug with id “id”.

@camera.aspect{aspect: NUMBER, index: NUMBER}

Set screen aspect ratio.

@camera.dolly{rate: NUMBER}

Set camera dolly rate 

@camera.location{x: INTEGER, y: INTEGER, z: INTEGER}

Set camera absolute location.

@camera.move{x: NUMBER, y: NUMBER, z: NUMBER}

Move camera a relative amount.

@camera.orbit{pitch: NUMBER, yaw: NUMBER}

Set pitch and yaw of camera.

@camera.pan{x: INTEGER, y: INTEGER}

Move camera horinontally and vertically.

@camera.params{}

Output camera configuration.

@camera.pivpnt{x: NUMBER, y: NUMBER, z: NUMBER}

Set camera pivot point (for orbit).

@camera.reset{mode: STRING}

Reset camera to defaults.

@camera.rotate{x: INTEGER, y: INTEGER, z: INTEGER}

Rotate camera around x, y, z.

@camera.select{camera: NUMBER}

Select camera “camera” for @camera.xxx{} commands.

@camera.shake{frames: NUMBER, maxpixels: NUMBER}

Shake camera for “frames” frames, by “maxpixels”.

@camera.view{camera: NUMBER}

Select camera to view (0-7).

@camera.zoom{zoom: INTEGER}

Set camera zoom (default = 16)

@color.background{red: INTEGER, green: INTEGER, blue: INTEGER}

Set microM8 background to R,G,B (0,0,0 to 1.0,1.0,1.0).

@color.depth{color: NUMBER, depth: NUMBER}

Set voxel Z-depth for color index.

@color.offset{color: NUMBER, offset: NUMBER}

Set Z-Axis 3D offset -100 to 100 for color index.

@color.palette{palette: STRING}

Select color palette to modify (eg. “HGR”) (used by other @color.xxx{} commands.)

@color.reset{}

Reset depths and R,G,B values.

@color.rgba{color: INTEGER, red: INTEGER, green: INTEGER, blue: INTEGER, alpha: INTEGER}

Set R,G,B,A for a given palette index.

@color.rotate{low: NUMBER, high: NUMBER, change: NUMBER}

Rotate palette R,G,B,A values between “low” and “hi”, with by “change”.

@color.text{c: NUMBER, r: NUMBER, g: NUMBER, b: NUMBER, a: NUMBER}

Set text palette color 15 r,g,b,a.

@color.tint{r: NUMBER, g: NUMBER, b: NUMBER}

Set palette tint.

@counter.bump{counter: NUMBER}

Bump a counter manually.

@counter.set{mode: STRING, address: NUMBER, counter: NUMBER}

Set a counter to count “read”/”write”/”exec” accesses by CPU to a particular address.

@counter.value{counter: NUMBER}

Read bump counter.

@cpu.prodos{enabled: NUMBER}

Enable prodos compatability shims in micro mode.

@cpu.speed{warp: NUMBER}

Set CPU speed factor (1.0 = normal).

@cpu.zeropage{enabled: NUMBER}

Enable / disable zero page emulation in micro mode.

@cursor.hide{}

Hide soft cursor in micro mode.

@cursor.pop{}

Restore cursor position in micro mode.

@cursor.push{}

Save cursor position in micro mode.

@cursor.show{}

Show soft cursor in micro mode.

@disk.info{drive: NUMBER}

Get mounted volume name for drive 0 or 1.

@disk.insert{drive: NUMBER, volume: STRING}

Insert disk in drive 0 or 1.

@disk.swap{}

Swap disks in drive 0 or 1.

@dos.append{filename: STRING}

Open a file in append mode.

@dos.cd{path: STRING}

Change working directory for micro mode commands.

@dos.chain{filename: STRING}

Chain execute the specified basic file.

@dos.close{filename: STRING}

Close a file.

@dos.copy{src: STRING, dest: STRING}

Copy a file from “src” to “dest”.

@dos.cp{src: STRING, dest: STRING}

Alias for @dos.copy{}.

@dos.del{path: STRING}

Delete a file from filesystem.

@dos.dir{path: STRING, spec: STRING}

Directory a path with wildcards.

@dos.ls{path: STRING, spec: STRING}

Alias for @dos.dir{}.

@dos.mkdir{path: STRING}

Make directory.

@dos.mount{path: STRING, drive: NUMBER}

Mount a disk image in drive 0 or 1.

@dos.open{filename: STRING}

Open a dos file.

@dos.param{index: NUMBER}

Get param value.

@dos.paramcount{}

Get number of params.

@dos.programdir{path: STRING}

Set a program working dir.

@dos.read{filename: STRING}

Open a file for read access.

@dos.rm{path: STRING}

Alias for @dos.del{}.

@dos.write{filename: STRING}

Open a file in write mode.

@draw.arc{x: NUMBER, y: NUMBER, start: NUMBER, end: NUMBER, radius: NUMBER, c: NUMBER}

Draw an arc.

@draw.box{x0: NUMBER, y0: NUMBER, x1: NUMBER, y1: NUMBER, c: NUMBER}

Draw a rectangle.

@draw.circle{x: NUMBER, y: NUMBER, radius: NUMBER, c: NUMBER}

Draw a circle.

@draw.line{x0: NUMBER, y0: NUMBER, x1: NUMBER, y1: NUMBER, c: NUMBER}

Draw a line.

@draw.poly{x: NUMBER, y: NUMBER, sides: NUMBER, radius: NUMBER, c: NUMBER}

Draw a polygon.

@feature.close{id: NUMBER, comment: STRING}

Close a feature request with comment.

@feature.comment{id: NUMBER, comment: STRING}

Add a comment to feature request.

@feature.create{summary: STRING, body: STRING, capture: NUMBER}

Create a feature request.

@feature.list{}

Show feature list.

@feature.load{id: NUMBER}

Load a feature request.

@feature.show{id: NUMBER}

Show a feature request.

@fill.box{x0: NUMBER, y0: NUMBER, x1: NUMBER, y1: NUMBER, c: NUMBER}

Draw and fill a box.

@fill.circle{x: NUMBER, y: NUMBER, radius: NUMBER, c: NUMBER}

Draw and fill a circle.

@fill.point{x: NUMBER, y: NUMBER, c: NUMBER}

Flood fill at a point.

@fill.poly{x: NUMBER, y: NUMBER, sides: NUMBER, radius: NUMBER, c: NUMBER}

Draw and fill a polygon.

@fill.screen{c: NUMBER}

Fill a screen with color index.

@gfx.cubegr{}

Enter default cube graphics mode.

@gfx.cubeline{x1: NUMBER, y1: NUMBER, z1: NUMBER, x2: NUMBER, y2: NUMBER, z2: NUMBER, c: NUMBER}

Draw a 3D line in cube graphics.

@gfx.cubeplot{x: NUMBER, y: NUMBER, z: NUMBER, c: NUMBER}

Draw a 3D point in cube graphics.

@gfx.hgrpixel{size: INTEGER}

Set HGR pixel size in dot mode rendering.

@image.draw{image: STRING, brightness: NUMBER, method: NUMBER, perceptual: NUMBER}

Draw an image with a dither mode to current display.

@imagemap.add{symbol: STRING, image: STRING}

Add an image map.

@imagemap.clear{}

Clear image maps.

@input.uppercase{mode: INTEGER}

Enable or disable uppercase only input.

@key.[a-z]{value: STRING}

Simulate Ctrl+Shift+<key> keypress.

@key.type{keys: STRING, cps: NUMBER, block: NUMBER}

Type string “keys” into vm at rate of “cps” cps.  Block if “block” = 1.

@layer.pos{slotid: INTEGER, x: STRING, y: STRING, z: STRING}

Set percent position of vm layers in “x”, “y”, “z” space.

@light.ambient{level: NUMBER}

Set ambient light level to “level” (0.0 – 1.0).

@light.diffuse{level: NUMBER}

Set diffuse light level to “level” (0.0 to 1.0).

@mem.lock{address: NUMBER, value: NUMBER}

Lock a memory address to update after “value” is written to it.

@mem.peek{address: NUMBER}

Peek a memory address.

@mem.poke{address: NUMBER, value: NUMBER}

Poke a memory address.

@mem.range{base: NUMBER, count: NUMBER}

Display a memory range, starting at “base”, for “count” values.

@mixer.master{level: NUMBER}

Set master mixer volume between 0.0 – 1.0

@mixer.mute{mute: INTEGER}

Mute master mixer volume.

@mixer.speaker{level: NUMBER}

Set 1 bit speaker volume between 0.0 – 1.0

@mode.font{mode: INTEGER}

Set font mode (0-15).

@mode.hgr{enabled: NUMBER}

Set hgr render mode.

@music.chanselect{channel: NUMBER}

Takes a number from 1 to 6.

@music.instrument{instrumentfile: STRING}

Set tone generator instrument params to those contained in a specified instrument .snd file

@music.notes{notes: STRING}

Plays a series of notes based on the following syntax:

Lx – Specifies the length of the following note(s). Higher is longer.
Ab3 – Specifies the note and the octave, for example C2 or D#5
Rx – “Rests” (plays nothing) for the length of x (same as L)
X – Stops playing a note
O – Causes the song to loop indefinitely.
P – Causes the player not to start immediately (Pause)
U – Causes the player to start (Unpause)

So for example @music.notes{“L1CD#EL3FGbA”} will play the notes C, D# and E in succession with the length of 1 (an eighth note) and then the notes F Gb and A with a length of 3 (a quarter note)

L values:

L0: Sixteenth note (1 step)
L1: Eighth note (2 steps)
L2: Dotted Eighth note (3 steps)
L3: Quarter note (4 steps)
L4: Dotted Quarter note (6 steps)
L5: Half note (8 steps)
L6: Dotted Half note (12 steps)
L7: Whole note (16 steps)
L8: Dotted Whole note (24 steps)
L9: Double Whole note (32 steps)

Notes: The first track added to a song determines its length, so ensure you add the longest melody first. Melodies added to additional tracks will be truncated if their length is longer.

Adding O to the end of the first melody programmed will cause the song player to loop indefinitely after the end of that melody is reached. Otherwise, playback will stop at that point and the melody / song will be erased.

While the song is playing, you can place notes on additional tracks by using the @music.chanselect{#} function to switch to a different track, and then using @music.notes{…} again.

If you use @music.notes on a track that has already had notes added to it, those notes will be replaced by the new ones, and this will be immediately reflected in playback.

Once the music stops (either because there is no loop and the end has been reached or you invoke @music.stop{}) the song is erased. However you can use @music.pause{} and @music.resume{} to pause the song, make changes, and then continue playback.

You can also use the P (pause) ‘note’ at the start of the @music.notes string to prevent the song player from beginning playback once notes are added. Once you have added all of the notes to the various tracks you require, conclude the last entry with a U. This will cause playback to begin.

@music.pattern{songorder: INTEGER}

Plays from a specified song order number NOT the pattern number, based on the first pattern in the order being 0. For example, 2 would play the third pattern in the song order, not pattern 2.

@music.pause{}

Pause playing music.

@music.play{songfile: STRING}

Play a specified microTracker .sng file

@music.resume{}

Resume paused music playback.

@music.speed{speed: NUMBER}

Sets the speed in BPM.

@music.stop{}

Stop music playback.

@music.tone{frequency: NUMBER, duration: NUMBER}

Play a tone of frequency “frequency”, duration “duration” (ms).

@overlay.filename{image: STRING}

Overlay the screen with a static PNG (for example, to create a watermark)

@paddle.button{a: NUMBER}

Presses paddle button “a”.

@paddle.value{index: NUMBER, value: NUMBER}

Sets the paddle value (0-255, 127 is center)

@paddle.swap{a: NUMBER, b: NUMBER}

Swap paddles “a” and “b” (a = 0 – 3, b = 0 – 3).

@render.dhgr{mode: NUMBER}

Set dhgr render mode (0-5).

@render.hgr{mode: NUMBER}

Set hgr render mode (0-5).

@restalgia.play{file: STRING, loop: NUMBER}

Play restalgia recording.

@scan.jumps{recording: STRING, count: NUMBER}

Scan a game recording looking for addresses jumped to a certain number of times.

@scan.sequence{file: STRING, NUMBER, … }

Scan a game recording looking addresses that had values written in a particular sequence (eg. 5, 4, 3, 2, 1).

@screen.contains{string: STRING, line: NUMBER}

Returns 1 if screen contains “string”.

@screen.read{line: NUMBER, start: NUMBER, end: NUMBER}: STRING

Returns trimmed text at line “line”, between columns “start” and “end”.

@share.command{vm: NUMBER, command: STRING}

Send a command to remote vm.

@share.connect{host: STRING, port: NUMBER, vm: NUMBER}

Connect current vm “vm” to remote host and port.

@share.controls{vm: NUMBER, target: STRING, profile: STRING}

Select a control profile for a remote vm.

@share.endremotes{}

Disconnect any remote vms from microM8.

@share.getcontrol{control: STRING, varname: VARIABLE}

Get control state into local var name “varname”.

@share.input{vm: NUMBER, command: STRING}

Send command “input” to remote vm.

@share.transfer{vm: NUMBER, user: STRING}

Transfer ownership of remote vm to another microLink user.

@string.wrap{text: STRING, width: NUMBER, start: NUMBER}

Format text with word wrap to width “width”.

@system.boottime{}

Get system start time.

@system.catalog{}

Invoke microFile file manager.

@system.disableslot{}

Disable to current slot.

@system.exit{}

Quit microM8.

@system.feedback{}

Launch Feedback tool.

@system.getkey{key: STRING}

Retrieve system key value data.

@system.hasnetwork{}

Returns 1 if microM8 has a network connection.

@system.ignoreaudio{enabled: NUMBER}

Ignore (mute) audio from the current vm.

@system.launch{file: STRING}

Launch a specified file “file”.

@system.log{ STRING, … }

Prints out a log message to the console window.

@system.monitor{}

Start legacy system monitor.

@system.mousekeys{mode: INTEGER}

Enable mouse keys support.

@system.nbi{prompt: STRING, var: STRING, max: NUMBER}

Non breaking input.  Collect chars if available until enter pressed (up to max chars) and put in var named “var”.

@system.new{vm: NUMBER, command: STRING}

Init vm “vm” with command “command”.

@system.noaspect{enabled: NUMBER}

Enable or disable changing aspect ratio.

@system.nobreak{enabled: NUMBER}

Enable or disable Ctrl+C break in basic.

@system.norestore{enabled: NUMBER}

Enable or disable restore.

@system.pause{ms: NUMBER}

Pause for “ms” milliseconds.

@system.setkey{key: STRING, value: STRING}

Set system key value under “key” to “value”.

@system.setmotd{motd: STRING}

Sets the server message of the day to “motd”.

@system.showmotd{}

Fetch and display message of the day.

@system.spawn{dialect: STRING}

Spawn a subshell running dialect “dialect” (“fp”, “int”, “logo”, “shell”).

@system.switch{vm: INTEGER}

Switch to vm “vm” (0-7).

@system.textbox{x: NUMBER, y: NUMBER, w: NUMBER, h: NUMBER, content: STRING, shadow: NUMBER, window: NUMBER}

Draws a text box with optional shadow, content and windowing.

@system.thaw{path: STRING}

Unfreeze a snapshot.

@system.uptime{}

Returns uptime in milliseconds since system start.

@text.color{fg: INTEGER, bg: INTEGER}

Set text foreground and background color.

@text.echo{filename: STRING, pageclear: NUMBER}

Echo text file to the screen, with optional page clear.

@text.font{font: INTEGER}

Sets the system font from one available to the machine profile.

@text.reset{color: INTEGER}

Reset color and size.

@text.shade{color: INTEGER}

Set text shade opaque (0) to transparent (7).

@text.size{mode: INTEGER}

Set font size (0 – 15).

@textdraw.color{color: NUMBER}

Set color for HGR text.

@textdraw.height{size: NUMBER}

Set height for HGR text.

@textdraw.inverse{enabled: NUMBER}

Set inverse for HGR text.

@textdraw.pos{x: NUMBER, y: NUMBER}

Set position for next drawn HGR text.

@textdraw.print{str: STRING}

Draw a text string in HGR.

@textdraw.width{size: NUMBER}

Set the width for HGR.

@user.setkey{key: STRING, value: STRING}

Set user key value “key” to “value”.

@video.play{file: STRING}

Play “video”

@video.record{file: STRING}

Start recording vm video to a local file.

@video.slice{file: STRING, outfile: STRING, start: NUMBER, end: NUMBER}

Cut a chunk out of a recording into a new recording (times in ms from start).

@video.stop{}

Stop video recording.

@vm.default{}

Switch redirection off.

@vm.disable{vm: INTEGER}

Disable vm number “vm”. 

@vm.enable{vm: INTEGER}

Enabled vm number “vm”.

@vm.exec{vm: NUMBER, command: STRING}

Execute a command in vm “vm”.

@vm.id{}

Get the current vm id.

@vm.pause{ms: NUMBER}

Pause the current vm for “ms” milliseconds.

@vm.redirect{vm: NUMBER}

Redirect all @commands to vm “vm”.

@vm.restart{}

Reset current vm.

@vm.select{vm: NUMBER}

Select “vm” for input/output.

@vm.target{}

Returns target vm for @commands.

@vm.var{vm: NUMBER, varname: NUMBER}

Returns value of variable in vm “vm”.

@window.add{name: STRING, sx: NUMBER, sy: NUMBER, ex: NUMBER, ey: NUMBER}

Define a virtual window on the screen (up to 80 x 48), with name “name”.

@window.use{name: STRING}

Switch to use window “name”.