Mode 0 Screen Editor v1

By Robert Sprowson

Originally published in EUG #24

Introduction to EDIT

A while ago, I wrote a Mode 0 screen editor in BASIC as my scanner uses this mode so editing is essential. Sorry if it's a little slow (I think it's the huge offset calculator starting ?&3000 DIV MOD DIV MOD DIV MOD, etc). This is on the disk too.

For those looking at the listing, everything is done using GOSUBs instead of PROCs because there was one which just wouldn't return properly (A bug in BASIC perhaps!) and also there are less than 256 bytes of free memory if I remember correctly which makes PROCs impossible to do as BASIC copies the 6502 stack onto the BASIC stack during a PROC - resulting in a "No Room" error.

Further details appear in the EDITREM program.

Since then, I have given up on the BBC to edit scans. Instead, I send them up a serial link to my PC as Windows BMP files and edit them in NEOPAINT then send them back when I've finished. Believe me, it's much faster in the long run. Incidentally, this letter was typed on my PC!


Execute it from the Utilities Menu or type CHAIN."U.EDIT" (RETURN) at the BASIC prompt. If necessary, insert the disk with the file on in the disk drive then when the speaker beeps, replace the original program disk.


Cursor keys Move pixel pointer around the screen
SPACE Reveal where the cursor currently is
S Save the image to the file $.OUTPUT on the program disk
M Move the selected area. Drag a box out then press COPY. Drag the moving box then press COPY to paste it
P Paste the image currently held on the clipboard ($.EDITCLP)
C Copy. Same procedure as move
F Fill. First, choose whether to fill Black/Grey/White then drag out a box to the area to be filled then press COPY. The clipboard is unaffected
B Box the area by dragging a box as usual, and leave it there on pressing COPY
T Type text (Do not press DELETE) at the current cursor position. If RETURN is pressed, the text is set in columns
E Call editor. Drag out an area then press COPY. The chosen area is saved and so is the current screen (to $.OUTPUT). The screen mode then changes and the area can be edited using TAB and the cursor keys. Press COPY to overlay the modified version

Mode 0 Screen Editor Comments

M$ = current message

DOTX & DOTY = current cursor position

STRTX & STRTY = start cursor position before dragging

(BRX,BRY) & (TLX,TLY) = bottom right and top left x and y coordinates of original box saved

A = internal counter, inkey and general pass parameters thingy

F = always used as the file#

OVR = isolated bit taken from the clipboard file as viewed in the order that it was saved and the order it is being loaded in in

FLG = set 0 if the chosen bit (see OVR) wasn't set and vice versa

PASS = counting loop used in the Mode 5 module and also when drawing a box (hence will always be a mutliple of 2)

SCRN = used in the Mode 5 module and initially set to &140 less that the bottom of the screen memory (as in the genric section that follows &140 is added back on) for the mode

LOC = current byte in question being poked

SVTLX = used in the two versions of the loading routine (see MODE5 module, around line 700) to keep the original value saved while the actual value is incremented

TMPX and TMPY = used to provide compatibilty between routines. i.e. to pass parameters and count things in loops

CNSTY and CNSTX = used when dragging out a box. Effectively set the stp of the FOR...NEXT loop to enable the box the be dragged from any corner

HINDX and EINDX = used when the appropriate whole selected bytes are to be saved. Home index = how many bits in from the MSB of the byte the cursor is at and End index = how many bits in from the MSB too 23, 0, 10, 12 ... is used to disable the cursor. If there are any suspicious +1's anywhere, it's usually because natural numbers start at 0,1 but the co-ordinate system starts at 0,0

EDIT is the startup and loading part; EDITTMP is used internally as a temporary file when the move option is chosen and will be deleted;

EDITCRE the core program which is where almost all execution time is spent; EDITENL contains the pixel by pixel editor; EDITCLP is the clipboard file in the format (strtx,strty)(dotx,doty)(bytes... To avoid the "Can't extend" error, ensure the disk is *COMPACTed. No, it won't run across the tube as it pokes memory addresses.


Within the core program only: 'SIZE?' means that the selected area to zoom in on was greater than 30x40; 'WIDTH?' and 'DEPTH?' mean that the selected area didn't enclose any pixels; 'CANNOT' is given by the paste command if there is no clipboard file on the disk.

Blow by blow

*FX3,4 restores output to the screen when re-entering fron 'editenl' as it is turned off in that program to jab keys into the keyboard buffer;

*FX4,1 makes the cursors ASCII; HIMEM is dropped as the message area is stored here later.
*FX12,8 slows the keyboard repeat to prevent delays while the pixel-pointer catches up with the keyboard buffer.

Is made up of many GOSUBs; each of which are used by the command table right at the beginning. In order of appearance they are: Keypresses are detected and if cursor keys then the pixel-pointer is moved else there is a check to see if it is one of the reserved words save what was in the message area (eight letters each taking 8 bytes) just below screen memory then print the message using MOVE and VDU5.

Restore those by Highlight the cursor with a 2x2 box by starting (x-2,y-2) from the current cursor position then increasing the co-ordinates. If the point is off the screen then nothing is plotted to avoid half the box appearing on the other side of the screen. Mass calculation to locate any pixel on the screen uses true (x,y) co-ordinates measured from top left (0,0) to bottom right (639,255).

Expand a box by seeing which of the cursors was pressed and adding or subtracting from DOTn. CNSTX and CNSTY allow the box to be dragged starting at any corner, although on pressing CHR$(135) they are sorted into size order so that STRTn is top left and DOTn is bottom right. If the box has no depth or width then the user will be alerted of this.

Move box by adding to BOTH STRTn and DOTn instead of just DOTn as above. On pressing CHR$(135) it returns.

Save boxed area to nearest whole byte. (The individual bits required from each end is calculated later.)

Load in by getting a byte from the file ANDing it with a mask and then checking whether the chosen bit is set. Then get byte from screen memory and AND it with a negative mask to ensure the selected bit is set 0. Or the two together.

Clearing the area temporarily renames the clipboard file then creates its own by saving a load of VAL(M$) - using M$ to save variable names. Load in that file and restore the clipboard. 255=white; 0=black, 170=(10101010) therefore grey.

Select black, grey or white. No default if the question is not answered, it is asked again.

Get co-ordinates of the area last selected in the clipboard file. If it doesn't exist then print 'CANNOT' in the message area.

One pass version of the draw a pulsing box. This is only used by the box drawer so that the box is permanently left on the screen.

Enter text (DELETE and COPY are disabled). Pressing RETURN puts it in columns and XORs it so that if crossing a black/white boundary, it appears 50:50.

PROCedit drags a box, saves the area, saves the entire screen to $.OUTPUT, then CHAINs the Mode 5 extention module.

OPENIN the file to get co-ordinates, remove the cursor with VDU23, define variables and those which I want to save unaltered for later.

As with loadin above, except that if flag is set then a whole square is coloured in with a poking 255 into the screen memory. Print current pixel position, which can be increased up to the limit of the screen (29,39).

If TAB pressed then EXOR whatever was there with 255 but if pressed CHR$(135) then stop the editor and save Reverse of loadin except that if TLX8 isn't zero then some blank bits must be saved in the byte before the 'pixels' (squares on the screen) can be evaluated otherwise the file would be ((HINDX+(8-EINDX))*Y too short.

Print 'reloading' then emulate what '$.EDIT' does (loads in the screen, turn on the first pixel at TLHC) then insert 'P' into the key buffer and run '$.EDITCRE' which then jumps to 'paste' mode to insert the new version.

Robert Sprowson, EUG #24