Git Product home page Git Product logo

zxcircle's Introduction

ZXCircle - A fast circle algorithm for ZX Spectrum

Graphic routine in assembler (Z80) for drawing circles with ZX Spectrum.

This code was written in 2000, for pure fun and as just an exercise.

Compiling and running the code

The source code is a .asm text file that can be compiled with a Z80 assembler like Pasmo, and run in a Spectrum emulator like the Qaop/JS online emulator. You can use other assemblers, but with Pasmo you can directly generate a .tap file, ready to be loaded in the emulator. For Debian-based distributions we can install it by:

$ sudo apt-get install pasmo

Run the assembler with the --tap or the --tapbas:

$ pasmo -v --tapbas zxcircle.asm zxcircle.tap

Loading file: zxcircle.asm in 0
Finished loading file: zxcircle.asm in 235
Entering pass 1
Pass 1 finished
Entering pass 2
Pass 2 finished

Then we can load the .tap in Qaop and run the example code:

RANDOMIZE USR 53000

In this video you can see a performance comparison of both the original and new algorithms.

10 FOR i=1 TO 20
20 CIRCLE 128, 80, i
30 NEXT i
40 RANDOMIZE USR 53000

You can try it online with Qaop/JS, just run the following command once inside:

RUN

A deeper look into the code

The file zxcircle.asm contains two main functions: one for drawing pixels, labeled as plot, and another one for drawing circles, labeled circle. Also, the file includes an execution example placed at the address 53000, that draws a set of concentric circles growing in size.

For drawing pixels, two lookup tables are used: tabpow2, with powers of 2, and tablinidx, with the order of the 192 screen lines (remember that the ZX Spectrum used an interlaced access).

You can invoke the routine by placing the point coordinates at the addresses 50998 and 50999, and jumping to the address 51000

POKE 50998, 128
POKE 50999, 88
RANDOMIZE USR 51000

To invoke the circle routine, you must place the center coordinates at 51997 and 51998, and the radius at 51999, and then jump to the address 52000.

POKE 51997, 128
POKE 51998, 88
POKE 51999, 80
RANDOMIZE USR 52000

Resources

zxcircle's People

Contributors

ibancg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

zxcircle's Issues

Screen address finding.

https://retrocomputing.stackexchange.com/questions/20425/zx-spectrum-coordinates-to-bitmap-conversion-subroutine-acting-strange

Looking at the Y calculation code, I think it's a few bytes less/quicker than the look up algorithm you're using? I don't know how many T-States it is though.


  ld      hl,tabpow2
    ld      a,(x)
    and     7       ; x mod 8
    ld      b,0
    ld      c,a
    add     hl,bc
    ld      a,(hl)
    ld      e,a     ; e contains one bit set

    ld      hl,tablinidx
    ld      a,(y)
    ld      b,0
    ld      c,a
    add     hl,bc
    ld      a,(hl)      ; table lookup

    ld      h,0
    ld      l,a
    add     hl,hl
    add     hl,hl
    add     hl,hl
    add     hl,hl
    add     hl,hl       ; x32 (16 bits)

    set     6,h         ; adds the screen start address (16384)

Vs


000A            convert_xy:    ; convert (x,y) in BC to memory address in HL
000A                           ; assuming arguments are always in valid range

000A   79             LD   a,c       ; getting Y position bits [5:3] ...
000B   07             RLCA           ; adjust it for the address lower byte's
000C   07             RLCA           ; bits [7:5]
000D   E6 E0          AND  $e0       ; mask out the garbage
000F   B0             OR   b         ; mix in the X coordinate
0010   6F             LD   l,a       ; this is final result for address low byte

0011   79             LD   a,c       ; back to Y
0012   E6 07          AND  $7        ; bits Y[2:0] are already in place
0014   F6 40          OR   $40       ; make it $4000 base
0016   67             LD   h,a       ; intermediate state is set to H
0017   79             LD   a,c   
0018   0F             RRCA           ; moving bits Y[7:6] to close the gap
0019   0F             RRCA           ; that was taken by bits Y[5:3] before
001A   0F             RRCA      
001B   E6 18          AND  $18       ; mask out the garbage
001D   B4             OR   h         ; join with temporary in H
001E   67             LD   h,a       ; this is final address high byte
001F   C9             RET     


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.