Contact us
Leave a message

SMS2 Basic

It was supposed to be my masterpiece -- a BASIC extension supporting scalable coordinate systems, multi-screen handling, and commands for improved structured programming. I didn't quite finish it back then (1988), but a remaining bug in the line-drawing routine kept bugging me so much that 18 years later I picked up the assembler again...

Inspired by the graphics commands of the BASIC on an Olivette M20 (or was it an M24?), which we used to have at school, I also wanted to provide a BASIC for the C64 with graphics commands that referenced a user-defined coordinate system instead of pixel coordinates. This seemed particularly important to me for technical and scientific applications, for example for being able to represent the graphs of mathematical functions more easily within a suitable range of values -- though I didn't consider that it's still better to work with pixels for drawing the coordinate system itself (arrows, ticks)... I also picked up the clever trick from Olivetti of exploiting various mirror symmetries when drawing circles, so that ultimately only 1/8th of a circle needs to be calculated -- although I don't think I handled the necessary floating-point calculations very efficiently, so that drawing circles is still quite sluggish despite the value recycling.

Other special features

  • Use of hexadecimal and binary numbers ($D000, %11110010, etc.) in numeric expressions
  • Raster-line interrupt-based splitting of the screen into text and graphics (I always loved this on the Apple II...)
  • A possibility for merging multiple graphics pages into one "large" page -- I still have a Hardcopy program lying around somewhere that allows the output of such multi-screens on a Star NL-10 printer...

Download

sms2-basic.prg -- load with "comma-eight-comma-one" and start with SYS 32768 (located between $8000 and $9FFF)
demo.sms2.prg -- the demo program shown above

The following new commands are available:

ACTIVE n

Specifies which graphics page (0..7) to draw on.

BLANK

Clears a graphics page. If no specific page is specified, the current page is cleared; specifying ALL blanks all corresponding pages in MultiScreen mode.

BLOAD name [,dn] [TO adr]

Loads a program/file with secondary address 1, i.e., to the start address specified in the first two bytes. Optionally, the device number (dn) and/or an alternative start address (adr) can be specified.

BSAVE name [,dn [,m] FROM start TO end [FOR adr]

Saves the memory area specified by start and end to the specified device (dn). Optionally, an alternative load address can be specified in the file header (adr) and/or a value (0..7) can be specified to be written to the lower 3 bits of address 1 (the I/O ports of the 6510 processor) to selectively access RAM, ROM, or the character generator when saving.

CATALOG [dn]

Displays the disk's directory on the screen; if no device number (dn) is specified, 8 is used as the default. The command name is Apple II-inspired ;-)

CIRCLE (x, y) WITH r

Draws a circle with center point (x, y) and radius r

COLOR fg ON bg

Sets the foreground and background colors for graphics mode

DASH n

Specifies a bit pattern that is iterated through cyclically in drawing mode 3, resulting in either setting (1) or skipping (0) a point, depending on the bit value. DASH %11110000, for example, produces a dashed line, DASH %11001100 a fine dashed line, and DASH %10101010 a densely dotted line.

DOS <[cmd [, dn] | [dn]>

Sends a command to DOS (default device number is 8), for example, DOS "S:name",9 to delete a file on drive 9. Upon completion or if no DOS command is executed, the error channel is read and the floppy drive status is output (if in direct mode; if DOS is being used by a program, the output is omitted).

DRAWMODE <0|1|2|3>

Specifies whether all subsequently drawn shapes should delete (0), set (1), invert (2), or process the pixels they touch according to the bit pattern defined by DASH (3).

ELLIPSE (x, y) WITH (r1, r2) [TURN a]

Draws an ellipse with center point (x, y) and two radii (r1, r2); optionally, the ellipse can be rotated around its center point by any angle 'a'.

EXCHANGE n1 WITH n2

Exchanges the contents of the two specified graphics pages.

GMODE <0 | nx TO ny, n1 [, n2 ...] >

Specifies whether to draw on a single page (GMODE 0) or to use multi-screen mode. If the latter, the number of graphics pages to be joined in the X and Y directions is specified by TO, followed by a list of page numbers (row by row from top left to bottom right). GMODE 3 TO 1, 3, 5, 7 e.g. defines a composite image consisting of graphics pages 3, 5, and 7, with a width of 3 * 320 = 960 pixels and a height of 1 * 200 = 200 pixels.

GRAPHICS [FROM upper] [TO lower]

Activates graphics mode, optionally limited to the range of text lines specified with FROM and/or TO.

HIMEM adr

Sets the upper limit of the memory available to BASIC, for example, to use it as graphics memory. Caution: This will clear all variables!

IF cond THEN ... ELSE ...

If the condition cond is true, everything up to ELSE is executed; otherwise, the commands following ELSE are executed. ELSE must be on the same line as IF and -- like a regular command -- must be separated by colons on both sides.

KBDCLR

Clears the keyboard buffer.

LINE [(x1, y1] TO (x2, y2)

Draws a line from (x1, y1) to (x2, y2). If the first coordinate pair is omitted, the line is drawn from the last end position.

MOVE n1 TO n2

Moves (copies) the contents of one graphics page to another.

OLD

Opposite of NEW ;-). Restores an (accidentally) deleted program, provided no variable assignments have been made.

POLYGONE (x, y) WITH (dx, dy) FROM a1 TO a2 STEP da [TURN a]

Draws a (possibly open) polygon with center point (x, y) and extent (dx, dy) from angle a1 to angle a2 in angular increments of da, which can optionally be rotated around the center point by angle 'a'.

RAYS (x, y) FROM a1 TO a2 STEP da [TURN a]

This works essentially like a polygon, except that the corners are connected to the center point instead of to each other.

RECTANGLE (x, y) WITH (w, h) [TURN a]

This draws a rectangle with its bottom left corner at (x, y), width w, and height h. Optionally, it can be rotated around its bottom left corner by the angle 'a'.

REPEAT ... UNTIL cond

Loop with an exit condition; the enclosed instructions are executed until the condition is met. REPEAT and UNTIL are separated by colons, just like regular instructions.

RPOKE adr, val

Like POKE, except that data is always written to RAM, even in the I/O range from $D000 to $DFFF.

SCALE xmin TO xmax, ymin TO ymax

Sets the user-defined coordinate system. In MultiScreen mode, the settings refer to the combined image.

SHOW n

Specifies which graphics page should be visible. Caution: Since the VIC can only address 16 kB, the color memory of an 8 kB graphics page is always located in the corresponding other page of the current address range! Displaying page 6 ($C000 - $DFFF), for instance, will write the corresponding color information directly after it ($E000 - $E3FF), thus overwriting some of the content potentially stored on page 7 ($E000 - $FFFF)!

TEXT [FROM upper] [TO lower]

Switches to text mode, optionally limited to the text line range specified with FROM and/or TO (the remaining area will then display hires graphics).

WHILE cond DO ... LOOP

Loop with an enter condition; it will only run as long as the condition is true (i.e., it might not run at all). If the condition is false, the program simply searches for the next LOOP command and continues directly after it; so it's best to avoid using GOTO commands in the loop body! The WHILE-DO pair, like LOOP, is separated by colons, just like a regular command.

WINDOW (x1, y1) TO (x2, y2)

Sets a drawing area in graphics mode; parts of figures that lie outside the defined window are cropped.

The following new functions are also available:

ACOS(a)

Returns the arccosine of a.

ASIN(a)

Returns the arcsine of a.

Constant "0"

GRAD(a)

Converts an angle from radians to degrees.

JOY(n)

Returns the status of joystick 1 or 2; bitmask as in corresponding CIA registers (bits 0-4), but with bits set (not cleared!) when active.

KEYPRESSED

TRUE if there are characters in the keyboard buffer.

LPX / LPY

X or Y coordinate of the light pen.

PIXEL(x, y)

Indicates whether the pixel corresponding to the coordinates (x, y) is set (TRUE) or cleared (FALSE).

RAD(a)

Converts an angle specified in degrees to radians.

RPEEK(adr)

Like PEEK, except that it always returns the contents of the addressed byte from RAM (even where ROM ($A000 - $BFFF and $E000 - $FFFF) or the I/O area ($D000 - $DFFF) is normally located).

TRUE

Constant "-1" = $FFFF