I wanted to link the file from which i have the plot routine but the search engine of wos is disfunctional
Code: Select all
//plotcircle09_2
// zcc +zx -vn -lm plotcircle09_2.c -o plotcircle09_2 -lndos -create-app --list --c-code-in-asm
//https://www.z88dk.org/forum/posting.php?mode=quote&p=21291
#include <stdio.h>
#include <math.h> /* zcc and gcc NEEDS -lm now */
#include <graphics.h>
#include <spectrum.h>
//actualy i just brutaly copy/past like a ...
#include <sys/types.h>
#include <conio.h>
void __CALLEE__ plotz( int x, y) __naked {
// x,y both 16bit
#asm
//; plot d = x-axis, e = y-axis
pop bc //10t fetch return address
pop hl //10t fetch x
pop de //10t and y
push bc //11t first restore return address
ld d,l // 4t fetch x lsb 8bit value from hl
// y left over in reg_e
;write 1 pixel DE holds X,Y position left,down 0,0
pixel: ld a,191 ; 7t 191 is working, was 175
sub e ; 4t y = y1 or y2
; jr c,reit ;10t out of screen
pixel0: ld e,a ; 4t e = 191-y
pixel2: rra ; 4t bit 7=NC=0
scf ; 4t set carry
rra ; 4t bit 7=1
and a ; 4t reset carry
rra ; 4t bit 7=0 >> a=010xxxxx
xor e ; 4t y a=101xxxxx
and 248 ; 7t 248 = 11111000 >> factor 8, bit-wise grid Y, block off 8 lines
xor e ; 4t y a=010xx000
ld h,a ; 4t h points to block 0, 1 or 2
ld a,d ; 4t x= x1 or x2
rlca ; 4t
rlca ; 4t
rlca ; 4t 3x rotate left circulair, highest 3 bit are now lowest 3 bit
xor e ; 4t y
and 199 ; 7t B_11000111
xor e ; 4t y back
rlca ; 4t B_10001111
rlca ; 4t B_00011111
ld l,a ; 4t l = x = %000xxxxx
ld a,d ; 4t x
and 7 ; 7t %00000111
ld b,a ; 4t
inc b ; 4t b=1 to 8 ???
ld a,1 ; 7t %00000001
rotate: rrca ; 4t %10000000 %01000000 etc set pixel %01234567
djnz rotate ; ((4+13)*b)-5 = 12 to
or (hl) ; 7t
ld (hl),a ; 7t
#endasm
}
void plotcircle(int r, int s, float x , float y ){
int f ;
float xr , yr , p , xstr[512], ystr[512] ;
for (f=0 ; f<=s ; f++ )
{
p= 2*f*M_PI/s ;
xr=x+r*cos(p) ;
yr=y+r*sin(p) ;
xstr[f]=xr ;
ystr[f]=yr ;
// plot(xr,yr) ;
plotz(xr,yr) ; // xr,yr are float, plot(x,y)is int
if (f>0) draw(xstr[f-1], ystr[f-1],xstr[f], ystr[f]);
}
return 0 ;
}
void main (){
char key ;
int f ;
float r, s, x, y ;
printf("\xC\n");
draw( 0, 0, 255, 0);
draw(255, 0, 255,191);
draw(255,191, 0,191);
draw( 0,191, 0, 0);
printf("plot a circle, first enter value's\neg r=50 , s=36 , x=127.5 , y=87.5\n\n");
enter_value:
printf("Enter r : ") ;
scanf("%f", &r ) ;
printf("Enter s : ") ;
scanf("%f", &s ) ;
printf("Enter x : ") ;
scanf("%f", &x ) ;
printf("Enter y : ") ;
scanf("%f", &y ) ;
printf("\xC");
plotcircle( r, s, x , y );
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf(" Press 'y' to plot again, 'n' will quit");
getakey:
key = getchar() ;
switch(key) {
case 'y' : goto enter_value ;
break ;
case 'n' : return 0 ;
break ;
default : goto getakey ;
}
}
Code: Select all
; pasmo -d -1 -v --tap p2pd031.asm p2pd031.tap p2pd031.symbol
; quick compile in kate:
; pasmo -d --tap %f %n.tap %n.symbol
; point to point draw, by MAARTEN uit Arnhem 1988 or 1989, or earlier
; draws a line between 2 absolute points anywhere on screen
;x 0-255
;y 0-191 > (0,0,255,191) gives a full screen diagonal
; poke 'pixel+1' with 191 for full screen to LINE 23 or poke 175 for BASIC screen to LINE 21
; use in BASIC:
; DEF FN d(x1,y1,x2,y2)= USR start
; RANDOMIZE FN d(x,y,a,b) (= RANDOMIZE USR start !)
; (x1,y1,x2,y2)=(0,0,a,b) is Left Down Corner
;https://www.worldofspectrum.org/forums/discussion/comment/129919/#Comment_129919
;The display layout is easy to understand at the binary level:
;1. 16-bit Screen Memory Address in binary
; 010B BSSS LLLC CCCC (pixels)
; BB = block (0-2) indicates top third, middle third or bottom third of screen
; SSS = scan line (0-7) indicates the vertical pixel row within a character
; LLL = vertical character line (0-7) within a block
; CCCCC = horizontal character coordinate (0-31)
;2. 8-bit Pixel Coordinates
; (0,0) top left corner of screen
; X : CCCC CTTT (0-255)
; Y : BBLL LSSS (0-191)
; TTT is 0-7 and indicates the pixel position within a byte. 0=leftmost pixel position (bit 7)
;3. 8-bit Character Coordinates
; X : 000C CCCC (0-31)
; Y : 000B BLLL (0-23)
;4. 16-bit Attribute Address
; 0101 10BB LLLC CCCC
; changes by Chris Born 2016,2019
; changed vertical size from 175 to 191, poke @ A_pix cq adres pixel+1
; Written as asm file manualy with ZX disas 'monitor25000'
; ;;;all JP commands changed in JR (except "jp c,9465"), for speed some could be changed back
; removed a single call, saving 4 bytes and 27 tstate.
; moved the storing of HL' and removed 2 'exx' saving 2 bytes and 8 tstate per line
; ;;;chanced 'ld b,255, xor b for CPL, saving 2 bytes and 7t
; changed 'bit-tractor' reg value reg A from 254 to 1 and removed al 'manual CPL' stuff saving 7byte totaly in that part and 7+4+4+4+7+4=30t per pixel draw
;moved ld (kstate),bc so its set before the decision and needed only once thus saving 4 byte, no tstate
; removed leftover opcodes
DEF_ADR equ 23563 ; sysvar DEF_ADR, points to needed value's
;temporair sysvars used as temp storage
kstate equ 23556 ;sysvar 2nd key-buffer
kstate2 equ 23558
xptr equ 23647 ; sysvar used while editing line
seed equ 23670 ; used for RND, set with RANDOMIZE so, probably over written by "randomize usr start"
start equ 60700
org start ;
di ; faster without interrupts
exx
push hl ;st0>st1
ld (kstate2),sp ; store StackPointer
ld hl,(DEF_ADR) ; hl = actual RAM location in BASIC listing at position off the DEF FN
ld bc,4 ;
add hl,bc ; adres+4
ld d,(hl) ; var x1
ld c,8 ;
add hl,bc ; adres+4+8
ld e,(hl) ; var y1
ld a,191 ; 7t 191 is working, was 175, 'just poke it' C.B.
cp e ; 4t y = y1
jp c,reit ; 7t out of screen
; how to use ex af,af' here ; ld a,191
; sub e
; jp c,reit
; ex af,af' reversed y1 stored
ld (seed),de ; store adres of FN value's x1 and y1
add hl,bc ; adres+4+8+8
ld d,(hl) ; var x2
add hl,bc ; adres+4+8+8+8
ld e,(hl) ; var y2
; ld a,191 ; 7t 191 is working, was 175, 'just poke it' C.B.
cp e ; 4t a=191 y = y2
jp c,reit ; 7t out of screen error trap is done now
;2 bytes longer, but 10 tstate faster pixelroutine
push de
ld de,(seed)
; push hl ;st1>st2
; push bc ;st2>st3
call pixel ; check max 191 and write pixel_1 , cq plot 1st pixel
reloc1 equ $-2
; pop bc ;st3>st2 , obsolete after error-return
; pop hl ;st2>st1 , obsolete after error-return
pop de ; never obsolate sinc error trap is past by already
ld hl,(seed) ; fetch start h=x1, l=y1 , d=x2, e=y2
ld bc,257 ; b=1 c=1 direction vector cq quadrant ++
ld a,d
sub h ; x2-x1
jr nc,ad60742
ld b,255 ; 'right to left' start point off drawing is biggest x
neg ; a=-a
ad60742 ld d,a ;amount pixels horizontal
ld a,e
sub l ; y2-y1
jr nc,ad60752
ld c,255 ;
neg ;bc is 'direction' relative to actual cq last pixel
ad60752 ld e,a ;amount pixels vertical
ld (kstate),bc ; bc=0x0101 or 01FF or FF01 or FFFF
ld a,d
cp e ; compare len x with len y ax
jr nc,ad60767 ; if y longest , jump
ld l,d
xor a
ld b,a
jr ad60779
ad60767 or d ; a=d already, zero check
jr z,restoreSP
ld l,e
ld e,d
ld c,0 ;
ad60779 ld h,e
ld a,e
rra
; pixel loop
nextpix add a,l ; 4t
jp c,ad60790 ;10t
cp h ; 4t
jp c,ad60800 ;10t
ad60790 sub h ; 4t
ld d,a ; 4t
exx ; 4t swop 1a
ld de,(kstate) ;20t 0101 01ff ff01 ffff
jp ad60804 ;10t
ad60800 ld d,a ; 4t
push bc ;11t st up bc=??
exx ; 4t swop1b
pop de ;10t st down = equal
ad60804 ld hl,(seed) ;20t fetch start
ld a,e ; 4t 0,1 or 255
add a,l ; 4t +y
ld e,a ; 4t e=y
ld a,d ; 4t 0,1 or 255
inc a ; 4t
add a,h ; 4t max 255+1 amount, 255+1 = Carry AND 0
jr c,ad60836 ; 7+5t >= C+ ( Z or NZ)
jr z,restoreSP ; 7t >= NC+Z = exit
ad60819 dec a ; 4t NC+NZ
ld d,a ; 4t
ld (seed),de ;20t write start
call pixel ;17+pixel
reloc2 equ $-2
exx ; 4t swop
ld a,d ; 4t
dec e ; 4t
jp nz,nextpix ; here 2t per PIXEL can be won Back for 1 byte, the relocate list becomes 1 adres longer
jr restoreSP ; last jump can be 2t faster but 1 byte longer
ad60836 jr z,ad60819 ; >= C+Z (or nc+nz),
restoreSP ld sp,(kstate2) ; C+NZ (or nc+z) , any obsolete value will be dismissed
pop hl
exx ; restore HL' value for BASIC
ei
ret
reit ei ; dont di-halt
jp 9465 ;rom routine REPORT-B 'out of range'
;value x=255 always fits on screen, but y must be y <= 191 B_10111111
pixel_af ex af,af'
pixel ld a,191 ; 7t 191 is working, was 175
sub e ; 4t y = y1 or y2
; jr c,reit ;10t out of screen
pixel0 ld e,a ; 4t e = 191-y
pixel2 rra ; 4t bit 7=NC=0
scf ; 4t set carry
rra ; 4t bit 7=1
and a ; 4t reset carry
rra ; 4t bit 7=0 >> a=010xxxxx
xor e ; 4t y a=101xxxxx
and 248 ; 7t 248 = 11111000 >> factor 8, bit-wise grid Y, block off 8 lines
xor e ; 4t y a=010xx000
ld h,a ; 4t h points to block 0, 1 or 2
ld a,d ; 4t x= x1 or x2
rlca ; 4t
rlca ; 4t
rlca ; 4t 3x rotate left circulair, highest 3 bit are now lowest 3 bit
xor e ; 4t y
and 199 ; 7t B_11000111
xor e ; 4t y back
rlca ; 4t B_10001111
rlca ; 4t B_00011111
ld l,a ; 4t l = x = %000xxxxx
ld a,d ; 4t x
and 7 ; 7t %00000111
ld b,a ; 4t
inc b ; 4t b=1 to 8 ???
ld a,1 ; 7t %00000001
rotate rrca ; 4t %10000000 %01000000 etc set pixel %01234567
djnz rotate ; ((4+13)*b)-5 = 12 to
or (hl) ; 7t
ld (hl),a ; 7t
ret ;10t 7+4+7+4 +4+4+4+4+4+4 +7 +4+4+4+4+4+4+4 +7 +4+4+4+4+4 +7 +4+4 +7 +4 +((4+13)*1)-5 +7+7+10
;=170 minimum tstate and +((4+13)*7) = 289 tstate max per pixel draw
; only 3 adresses to be recalculated for an relocation, from which only TWO needs to be rewritten
rel_1 equ reloc1-start
defw rel_1
rel_2 equ reloc2-start
defw rel_2
relpix equ pixel+1-start
A_pix equ relpix
ent equ $
len equ ent-start
the end
;cleaned rewrite from MAARTENS point2point draw