Shop OBEX P1 Docs P2 Docs Learn Events
A question about mixing spin and C [solved] — Parallax Forums

A question about mixing spin and C [solved]

ReinhardReinhard Posts: 489
edited 2020-06-05 01:00 in Propeller 2
Hello, I am currently working on graphics on the P2 (as can easily be seen in the imperfect picture).
Is there a possibility to mix with fastspin C-sources and spin-sources to a binary. I have in mind to use the NTSC examples of Chip as a video driver and to create the image content with C, i.e. to fill the bitmap buffer area.

Thank's
Reinhard

Comments

  • Yes, mixing languages in fastspin is easy. If your main program is in C you can include a Spin object by writing something like:
    struct __using("NTSC_video.spin2") ntsc;
    
    and then access methods and variables with the usual C/C++ syntax, e.g.:
    cogid = ntsc.start(parameters);
    
  • Thank you for the fast answer. I try it soon as possible.

    Reinhard
  • hm, something I do wrong:
    I have this spin object in file NTSC_Frame.spin2
    '*********************************
    '*  NTSC 256 x 192 x 8bpp rgbi8  *
    '*********************************
    
    CON
    
      f_color	= 3_579_545.0		'colorburst frequency
      f_scanline	= f_color / 227.5	'scanline frequency
      f_pixel	= f_scanline * 400.0	'pixel frequency for 400 pixels per scanline
    
      f_clock	= 250_000_000.0		'clock frequency
    
      f_xfr		= f_pixel / f_clock * float($7FFF_FFFF)
      f_csc		= f_color / f_clock * float($7FFF_FFFF) * 2.0
    
      s		= 84			'scale DAC output (s = 0..128)
      r		= s * 1000 / 1646	'precompensate for modulator expansion of 1.646
    
      mody		= ((+38*s/128) & $FF) << 24 + ((+75*s/128) & $FF) << 16 + ((+15*s/128) & $FF) << 8 + (110*s/128 & $FF)
      modi		= ((+76*r/128) & $FF) << 24 + ((-35*r/128) & $FF) << 16 + ((-41*r/128) & $FF) << 8 + (100*s/128 & $FF)
      modq		= ((+27*r/128) & $FF) << 24 + ((-67*r/128) & $FF) << 16 + ((+40*r/128) & $FF) << 8 + 128
    
      video_pin	= 1
    
      ntsc_map	= $1000
    
    DAT		org
    
    ' Setup
    
    start	
    		
            	'hubset  ##%1_000001_0000011000_1111_10_00       'config PLL, 20MHz/2*25*1 = 250MHz
                    'waitx   ##20_000_000 / 200                      'allow crystal+PLL 5ms to stabilize
                    'hubset  ##%1_000001_0000011000_1111_10_11       'switch to PLL
    
    
    		rdfast	##256*192/64,##ntsc_map	'set rdfast to wrap on bitmap
    
    		setxfrq ##round(f_xfr)		'set transfer frequency
    		setcfrq	##round(f_csc)		'set colorspace converter frequency
    
    		setcy	##mody			'set colorspace converter coefficients
    		setci	##modi
    		setcq	##modq
    
    		setcmod	#%11_1_0000		'set colorspace converter to YIQ mode (composite)
    
    		cogid	.x			'enable dac mode in pin
    		setnib	.dacmode,.x,#2
    		wrpin	.dacmode,#video_pin
    		drvl	#video_pin
    
    ' Field loop
    
    .field          mov	.x,#35			'top blanks
    		call	#.blank
    
    		drvnot	#30
    
                    mov     .x,#192			'set visible lines
    .line	        call	#.hsync			'do horizontal sync
    		xcont	.m_rf,#0		'visible line
    		xcont	.m_av,#1		'after visible spacer
    		djnz    .x,#.line           	'another line?
    
                    mov     .x,#27			'bottom blanks
    		call	#.blank
    
    		mov	.x,#6			'high vertical syncs
    .vlow		xcont	.m_hl,#2
    		xcont	.m_hh,#1
    		djnz	.x,#.vlow
    
    		mov	.x,#6			'low vertical syncs
    .vhigh		xcont	.m_ll,#2
    		xcont	.m_lh,#1
    		djnz	.x,#.vhigh
    
    		mov	.x,#6			'high vertical syncs
    .vlow2		xcont	.m_hl,#2
    		xcont	.m_hh,#1
    		djnz	.x,#.vlow2
    
    		
    
                    jmp     #.field                 'loop
    
    ' Subroutines
    
    .blank		call	#.hsync			'blank lines
    		xcont	.m_vi,#0
    		xcont	.m_av,#1
    	_ret_	djnz	.x,#.blank
    
    .hsync		xcont	.m_sn,#2		'horizontal sync
    		xcont	.m_bc,#1
    		xcont	.m_cb,.c_cb
    	_ret_	xcont	.m_ac,#1
    
    ' Data
    
    .dacmode	long	%0000_0000_000_1011100000000_01_00000_0
    
    .m_sn		long	$7F010000+29		'sync
    .m_bc		long	$7F010000+7		'before colorburst
    .m_cb		long	$7F010000+18		'colorburst
    .m_ac		long	$7F010000+40		'after colorburst
    .m_vi		long	$7F010000+256		'visible
    .m_av		long	$7F010000+50		'after visible (400 total)
    
    .m_rf		long	$BF030000+256		'visible rfbyte 8bpp rgbi8
    
    .m_hl		long	$7F010000+15		'vertical sync high low 
    .m_hh		long	$7F010000+185		'vertical sync high high (200 total)
    
    .m_ll		long	$7F010000+171		'vertical sync low low
    .m_lh		long	$7F010000+29		'vertical sync low high (200 total)
    
    .c_cb		long	$507000_01		'colorburst reference color
    
    .x		res	1
    .y		res	1
    
    
    
    

    And the C - code is
    global
    struct __using("NTSC_Frame.spin2") ntsc;  //LINE 13
    

    and in main
    	cogid = ntsc.start();
    	printf("%d\n",cogid);
    

    give error
    Propeller2/forum/Video$ fastspin -2b --fixedreal  frame.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.1.11 Compiled on: May 28 2020
    frame.c
    |-NTSC_Frame.spin2
    Propeller2/forum/Video/frame.c:13: error: empty or undefined class used to define ntsc
    
    
  • The NTSC_Frame.spin2 file has no actual Spin methods, so no functions that the C code can call.
  • Yes I understand (a little bit)
    I am far away from spin programming.
    I need a spin method foo, PUB foo, which in turn calls me the asm routine bar. Is that correct?
    Thanks for patience
    Reinhard
  • It looks like the NTSC code is designed to run in its own COG. So you'd need something like:
    ' add this Spin method to the end of the NTSC code
    ' and have the C code call "obj.startNtsc()"
    PUB startNtsc() : id
      id := cognew(@start, 0)
    

    But I have not looked closely at this object, and I have no idea if this will work correctly. You'll also have to figure out where in memory the frame buffer is in order for the C code to write into that.
  • ersmith wrote: »
    It looks like the NTSC code is designed to run in its own COG. So you'd need something like:
    ' add this Spin method to the end of the NTSC code
    ' and have the C code call "obj.startNtsc()"
    PUB startNtsc() : id
      id := cognew(@start, 0)
    

    But I have not looked closely at this object, and I have no idea if this will work correctly. You'll also have to figure out where in memory the frame buffer is in order for the C code to write into that.

    Yes, the frame buffer is located at 0x1000, and C code can write into with following steps:
    1. Fill an localbuffer with data
    2. if the (local) buffer is ready
            unsigned char * dest;
    	dest = (unsigned char *) 0x1000;
    	memcpy(dest,&buffer[0],256*192);
    
    I tested this by first loading the program that writes the video buffer and then loading the NTSC_Frame.spin2 to see something on the monitor.

    I make the change in NTSC_Frame.spin2 at the end of file:
    PUB startNtsc() : id
      id := cognew(@start, 0)
    
    I can compile the spin2 file and it runs standalone, a composite video signal is generated and on monitor I can see random noise, the random content of bitmap buffer.


    but with call from C:
    struct __using("NTSC_Frame.spin2") ntsc;  //LINE13
    ntsc.startNtsc(); //LINE44
    
    I get error:
    knoppix@Microknoppix:~/Propeller2/forum/Video$ fastspin -2b --fixedreal  frame.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.1.11 Compiled on: May 28 2020
    frame.c
    |-NTSC_Frame.spin2
    /home/knoppix/Propeller2/forum/Video/frame.c:44: error: unknown identifier startNtsc in class NTSC_Frame
    /home/knoppix/Propeller2/forum/Video/frame.c:44: error: startNtsc is not a member of NTSC_Frame
    /home/knoppix/Propeller2/forum/Video/frame.c:44: error: unknown identifier startNtsc in class NTSC_Frame
    /home/knoppix/Propeller2/forum/Video/frame.c:44: error: startNtsc is not a member of NTSC_Frame
    /home/knoppix/Propeller2/forum/Video/frame.c:44: error: unknown identifier startNtsc in class NTSC_Frame
    /home/knoppix/Propeller2/forum/Video/frame.c:44: error: startNtsc is not a member of NTSC_Frame
    
    
  • In version fastspin 4.1.11 you'll have to use all lower case (startntsc instead of startNtsc) when referring to Spin methods from C, because all Spin method names are converted to lower case. (Spin is case insensitive, but C is case sensitive, so that's how 4.1.11 and earlier handled this).

    In fastspin 4.2.0 or later the symbol case sensitivity is kept along with the symbol, so this isn't a problem. So your best bet is probably to upgrade to the newer fastspin, but changing to all lower case will work too (and will continue to work in 4.2.0).

  • Thank you
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.1.11 Compiled on: May 28 2020
    frame.c
    |-NTSC_Frame.spin2
    sleep.c
    fmt.c
    posixio.c
    bufio.c
    errno.c
    memcpy.c
    frame.p2asm
    Done.
    Program size is 61684 bytes
    
    
Sign In or Register to comment.