I have written a short assembler routine for BBC/Electron MODE1 to both write and delete 16x16 pixel sprites from screen memory, shown below. As my first attempt to write a such a routine in assembler, I thought I would share it as I am sure that it is possible to optimize it further and also it maybe of interest to others.

The routine uses the EOR technique to first write the sprite to the screen by EORing it with with the contents of screen memory, then writing the result to screen memory. A second EOR step deletes the sprite by returning the contents of the screen memory to their original state.

The memory locations of the bitmap source and destination are passed to assembler by setting resident integer variables K% and N%. The BASIC in the code allows the sprites to be moved by up and down by pressing the 'Z' and 'X' keys.

I have commented the BASIC but ran out of memory trying to properly comment the assembler! The assembler routine is complicated by the need to increment the pointer to the destination memory location by (640-8)bytes every eighth row of pixels in MODE1 which is a real pain. The way bits are mapped to memory for MODE1 is shown in Appendix 'C' of the Electron Advanced User Guide.

The assembler routine contains a loop which is executed eight times, copying the nth and (n+8)th 16x1 row of pixels of the 16x16 bitmap on each pass of the loop. The two byte memory location of the source of each 16x1 row of pixels is stored in zero page at &70+&71 and &74+&75 with the memory location of the destination of these pixels at &72+&73 and &76+&77. These are copied from resident integer variables K% and N% by lines 910-950

Line 960 sets the 'Y' register to 0 which will be used as the loop counter. The loop counter is moved to the 'X' register by line 980.

Lines 1000 to 1100 first load bitmap source bytes, EOR them with the contents of the destination memory bytes, then write the result to the destination memory.

The awkward business of determining if the destination memory location of the (m+1) row of 16x1 pixels is 1byte or (640-8)bytes below the memory location of the current row of pixels is done by line 1130 with the addition being performed by lines 1140 and 1150. The loop is concluded by line 1180.

The sprites do flicker a bit when the code is run in BEEBEM but I suspect this flicker is minimal with a computer connected to a 1980s TV or CRT monitor.

I found one solution to make the 'add 8s disappear' by using three 256 byte look up tables - one each for N=N'+8, N=N'+8+8 and N=N'+8+8+8. This takes 3*256 bytes to implement so it is not a particularly elegant solution. The new code is below. Look up tales are created in BASIC by line 330, and 'read' by lines 1010, 1040 and 1070. The eight cycles needed to execute TYA:CLC:ADC#8:TAY are now replaced by a single four cycle LDA Absolute,X instruction.

Next, I am going to work on dp11's suggestion of using 8 sprite plotting routines depending on which row the sprite is going to be plotted.

Thank you all for your suggestions on improving my code. Tricky, your demos are excellent- I especially like the isometric pac-men!

I wanted to reduce the flickering of my sprites, so I reworked the BASIC code to make use of double buffering on a BBC Master by changing the ACCCON register (at &FE34) to switch the main and shadow video memory between the address space of the CPU and the video circuitry. It runs nicely under BeebEm but owning and Electron I have not been able to test it a real BBC Master - hopefully it works! The Assembler code should be unchanged since my last post. The latest code is shown below, but press <BREAK> after pressing <ESCAPE> to reset the ACCCON register else text typed into the machine may not be displayed. The screen should display "FIELD A" when video is displaying the contents of normal RAM and "FIELD B" when displaying the contents of shadow RAM.

Double buffering allows all sprites to be deleted in one go, then drawn again in their new position before flipping the video output. This allows for the next step which is to modify the 'blit16_loop' loop to delete all sprites in their old positions or to draw all sprites in their new positions with a single CALL from BASIC which should speed things up quite nicely...

Thanks, they are there to inspire and encourage.I've always coded for the been, but the shadow display seems like a great way to improve the look of your game.With eor, you could also move one at a time, it will still flicker a bit, but much less than clearing all and then redrawing all, but not as clean as your solution.

The assembler code has now been modified so that a single CALL deletes or redraws all of the sprites in one go. I also changed the sprites to spiders. Press 'Z' or 'X' to move the spiders up and down after they have all been drawn (this process takes a few 10s seconds).

Unfortunately to squeeze the additional BASIC needed to draw and animate the spiders in MODE 1 I have had to remove all the REM statements and use multi statement lines so the BASIC code has lost much of its readability.

I think I have the sprite handling code now for the basis of a reasonable game based off my December 1986 "Santa's Sleigh" MicroUser game which was written in BASIC. The next step to try and realise this eventual goal is to reorganise the code such that assembler and bitmaps fit inside a sideways RAM bank.