Hello,
When compiling a C project that features assembly code, I get the error

Code:

Error: symbol ':globals._FUNCTIONNAME' is undefined or out of scope


FUNCTIONNAME refers to a C function that is supposed to be defined in Assembly.
The code is present but the program fails to link.

I use the default example makefile including in the hello world program and all source files are including in the src/ directory.

Any help will be greatly appreciated!
What does your assembly source file look like?
RoccoLox Programs wrote:
What does your assembly source file look like?

It is the source code to the "Plane Jump" game.
The function I am getting the error in the is

Code:
_drawGameField



Code:
.assume adl=1
XDEF _drawGameField
XDEF _drawBG
XDEF _hue_to_1555RGB
OTHER_COLOR EQU 252


TRANSLATE_STRIDE EQU 8
;an array of structs 8 bytes wide, containing 32+240+32 entries
;+0 ypos, +1 sx, +4 w1, +5 w2, +6 w3, +7 w4
XREF _translate
;array of bytes, bits representing the encoded track: xxxx_1234. 32 entries
XREF _track

;do: ld iy,0 \ add iy,sp to set argument stack
;iy+3=arg0, iy+6=arg1, iy+9=arg2 ...
;
;Note: 0E30014h is a pointer for the buffer
;Note: 0E30200h is the start of the 512 byte color palette. (RGB 1555)
;NOte: 0E30800h is the start of CursorImage (1KB of high speed memory)

cur_track_block EQU 5  ;... variable this overwrites isn't being used again

tr_offset EQU 3
px_offset EQU 6
x_offset  EQU 9

;Simple acceleration by copying to and running from high speed memory
_drawGameField:
   ld de,0E30800h
   push de
      ld hl,dgf_start
      ld bc,dgf_end-dgf_start
      ldir
   pop hl
   jp (hl)
dgf_start:
   di
   ld iy,0
   add iy,sp
   push ix
      ;preconditioning
      ld bc,(iy+x_offset)
      ld hl,(0E30014h)
      add hl,bc     ;add start address to buffer
      ld (dgf_loadoffset),hl
      ;start address on translation
      ld a,(iy+px_offset)
      ld b,a
      ld c,TRANSLATE_STRIDE
      mlt bc
      ld ix,_translate
      add ix,bc
      ;get starting address on track array
      ld c,(iy+tr_offset)
      ld b,0
      ld hl,_track
      add hl,bc
      ex de,hl
      ;init values for main loop
      ld b,a
      inc b
      neg
      srl c
      ld c,a  ;px offset. some additional testing, yes?
      sbc a,a
      and a,OTHER_COLOR ;A is 0 or 252
      ld L,a
      ld a,b
      cp 33
      ld a,L
      jr nc,$+4
      xor a,OTHER_COLOR  ;there has to be a better way to suppress the flashing.
      ld (dgf_color_ins),a
      ld a,255
      ld (dgf_prevscanline),a
      
;      inc b
;      dec b
;      jr z,dgf_skipscanline
;draw 240 scanlines.
; on entry: B=rows of first tile row to draw, C=240
;           IX=&translate[t_offset], DE=&track[p_offset]
dgf_mainloop:
      ;ypos set to 255 if draw coordinate is outside the screen.
      ;since screen height is only 240. (probably?)Can't do -1 as it was
      ;defined as a uint8_t in the C program these values were genned in.
      ld l,(ix+0)      ;ypos
      inc l
      jr z,dgf_skipscanline
      dec l
      ;The section below solves a line skipping problem
dgf_prevscanline EQU ($-dgf_start+1)+0E30800h
      ld a,0
      cp l
      jr z,dgf_skipscanline   ;if repeating same line, skip. for performance
      inc a    ;If L==(A+1), is on track
      jr z,dgf_skip_repro
      add a,7
      cp l    ;but if A is still greater than L, interpolate. Else, cancel.
      jr c,dgf_skip_repro
      sub a,7
      ld l,a
      lea ix,ix-8
      inc b
      inc c
dgf_skip_repro:
      ld a,l
      ld (dgf_prevscanline),a
      ;end section
      ld h,160   ;half of screen width (320)
      mlt hl
      add hl,hl  ;finish multiply by 320
      ld a,(de)
      ex af,af'
      push bc
         push de
dgf_loadoffset EQU ($-dgf_start+1)+0E30800h
            ld bc,0
            add hl,bc
            ld bc,(ix+1)  ;
            add hl,bc     ;add start x. BCU and B known zeroes here.
            lea ix,ix+4
            push hl
            pop de
            inc de        ;precompute HL+1 and keep tracking it
dgf_color_ins EQU ($-dgf_start+1)+0E30800h
            ld a,0
            ld iyh,4
dgf_drawloop:   
            ld c,(ix+0)
            ex af,af'
            rrca
            jr c,dgf_drawscan
dgf_skipscan:   ex af,af'
            add hl,bc
            ex de,hl
            add hl,bc
            ex de,hl
            jr dgf_finish
dgf_drawscan:   ex af,af'
            dec c
            ld (hl),a
            ldir
            inc de
            inc hl
dgf_finish:      
            xor OTHER_COLOR
            inc ix
            dec iyh
            jr nz,dgf_drawloop
            lea ix,ix-8
         pop de
      pop bc
dgf_skipscanline:
      dec c
      jr z,dgf_endnow
      lea ix,ix+8
dgf_godjnznow:
      djnz dgf_mainloop
      ld b,65  ;Why does this number have to be twice as large as max px_offset?
      inc de
      ld a,(dgf_color_ins)
      xor OTHER_COLOR
      ld (dgf_color_ins),a
      jr dgf_godjnznow
dgf_endnow:
   pop ix
   ei
   ret
dgf_end:
   
   
   
   
   
   
   
   
   
   
   
;accel notes.
;106 pushes plus 2 more bytes writes to a complete row
;less inner: modify value
;inner:      push value 106 times, increment sp, push once more
_drawBG:
   di
   ld de,0E30800h
   ld hl,drawbg_seg1_start
   ld bc,drawbg_seg1_end-drawbg_seg1_start
   ldir
   push hl
      push de
      pop hl
      inc de
      ld bc,105
      ld (hl),0D5h  ;PUSH DE
      ldir
   pop hl  ;points to next step: drawbg_seg2_start
   ;copy in the h1555 routine as well.
   ld bc,hto1555_seg1_end-drawbg_seg2_start
   ldir
   call hue_to_1555_internal
   ld iy,0
   add iy,sp
   ld hl,(0E30014h)
   ld de,320*240
   add hl,de
   ld sp,hl
   ld b,240
   jp 0E30800h
   
   
   
;=============================================================================
;START COMBINED FAST RAM SEGMENTS
   
;segment 1: loads DE with value to be pushing. Use IY-6 as scratch
drawbg_seg1_start:
   ld (iy-6+2),b ;3
   ld de,(iy-6)  ;3: get A into DEU
   ld e,b        ;1
   ld d,b        ;1 = 8
drawbg_seg1_end:
;Immediately after seg1 is 106 instances of PUSH DE
drawbg_seg2_start:
   inc sp        ;1
   push de       ;1 = 2
   db 10h,-(8+2+106+2)
   ld sp,iy
   ei
   ret
drawbg_seg2_end:

hto1555_seg1_start:
.assume adl=0
hto1555_ramseg EQU (hto1555_seg1_start-drawbg_seg1_start+106)+0800h  ;sis jump
   ld b,30
   ld sp,0200h+01E2h  ;just after the 241st element
   ld de,32     ;to increment green
hto1555_reloc_loop:
   ld a,h    ;get red
   and 124   ;isolate red
   cp 124
   jr z,hto1555_noinc_red
   add a,4
hto1555_noinc_red:
   xor h
   and 252
   xor h
   ld h,a
   
   push hl
   push hl
   push hl
   
   ld a,L    ;get blue value, disregard green
   and 31    ;isolate blue
   cp 31
   jr z,hto1555_noinc_blue
   inc a
hto1555_noinc_blue:
   xor L     ;begin combine low byte with (possibly) new blue
   and 31    ;clear green bits so next xor will write them, leaving blue
   xor L
   ld L,a
   
   push hl
   push hl
   
   xor h     ;begin combine low with high to isolate all green bits
   and 224   ;keep high bits of L
   xor h     ;to write out all green bits on lower (from high)
   and 227   ;to remove all non-green bits
   cp 227
   jr z,hto1555_noinc_green
   add hl,de
hto1555_noinc_green:
   ; push hl
   ; push hl
   ; push hl
   ; push hl
   ; push hl
   push hl
   push hl
   push hl
   djnz hto1555_reloc_loop
   jp.lil hto1555_continue
.assume adl=1
hto1555_seg1_end:

;END COMBINED FAST RAM SEGMENT
;=============================================================================


;Computing most of this in 8.8 fixed point, represented as an int.
;Note: 1524 comes from 65536/43, where 43 is roughly (256/6), or 1/6th of
;a complete rotation around our "special" color wheel.
;  0- 43: N*1524
; 44-127: 65535
;128-171: -(N-171)*1524
;172-255: 0
;
;1555: IRRR_RRGG:GGGB_BBBB
hue_to_1555_internal:
hto1555_smc EQU $+1
   ld a,0
   inc a
   ld (hto1555_smc),a
   ld c,a
   jr hto1555_internal_skip
_hue_to_1555RGB:
   di
   ld hl,hto1555_seg1_start
   ld de,0E30800h+(hto1555_seg1_start-drawbg_seg1_start)+106
   ld bc,hto1555_seg1_end-hto1555_seg1_start
   ldir
   ;start calculating
   pop bc   ;C = hue (0-255)
   push bc
   ld a,c
hto1555_internal_skip:
   call hto1555_single  ;get G. bits in GGGG_G***. Moveto: GGG*_**GG
   and a,248    ;GGGG_G***
   rlca         ;GGGG_***G
   rlca         ;GGG*_**GG
   ld h,a       ;save raw to high (reprocess later to replace upper bits
   and a,224    ;GGG0_0000
   ld l,a       ;save processed to low
   ld a,c
   sub a,171    ;blue offset
   call hto1555_single ;get B. bits in BBBB_B***. Moveto: ***B_BBBB
   and a,248    ;BBBB_B***
   rrca         ;*BBB_BB**
   rrca         ;**BB_BBB*
   rrca         ;***B_BBBB
   or L
   ld L,a       ;GGGB_BBBB (low byte)
   ld a,c
   sub a,85     ;red offset
   call hto1555_single ;get R. bits in RRRR_R***. Moveto: 1RRR_RR**
   and a,248    ;RRRR_R000
   inc a        ;RRRR_R001
   rrca         ;1RRR_RR00
   xor h        ;1R^G
   and 252      ;####_##00
   xor h        ;1RRR_RRGG
   ld h,a       ;HL is now set up for stuffs.
   ;get ready to write to the buffer thing.
   ld a,MB      ;save MBASE
   push af
      ld a,0E3h
      ld MB,a
      jp.sis hto1555_ramseg
hto1555_continue:
   pop af
   ld MB,a
   ret

;in: A=hue, out A= (H_GREEN).
;(To get red, pass in A = A-85. To get blue, pass in A = A-171
;destroys HL
hto1555_single:
   cp 44
   jr nc,hto1555s_skipasc
hto1555_slide:
   ld  e,a
   ld  d,a
   add a,a
   add a,a
   add a,e  ;high byte const of 1524 (5) as repeated adds
   ld  e,224 ;low byte const of 1524 (224)
   mlt de
   add a,d ;10b
   ret
hto1555s_skipasc:
   bit 7,a
   jr nz,hto1555s_skipmax
   ld a,255
   ret
hto1555s_skipmax:
   sub a,172
   jr nc,hto1555s_skiptomin
   cpl     ; -(N-171) but we can -(N-172)+1. I think?
   jr hto1555_slide
hto1555s_skiptomin:
   xor a
   ret
   
   
;Note: 0E30200h is the start of the 512 byte color palette. (RGB 1555)
;NOte: 0E30800h is the start of CursorImage (1KB of high speed memory)

So instead of putting XREF before for the function name, try replacing it with "public _functionName" and see if that works for all of those.
RoccoLox Programs wrote:
So instead of putting XREF before for the function name, try replacing it with "public _functionName" and see if that works for all of those.

I tried that but now I am recieving a new error.

Code:
call _drawBG
call? [31] @ez80.word [1] (CALM)
Error: variable term used where not expected.

This now looks like a syntax error instead of a linker error
Okay, sorry I forgot something. Also add the line, "section .text" after the line, ".assume adl=1".
RoccoLox Programs wrote:
Okay, sorry I forgot something. Also add the line, "section .text" after the line, ".assume adl=1".

Now it is saying that ".assume adl=1" is an illegal instruction

Code:
Processed: .assume adl=1
Error: illegal instruction.
Try just putting, "assume adl=1" without the "."
RoccoLox Programs wrote:
Try just putting, "assume adl=1" without the "."

Another error! haha

Code:

public _translate
public? [25] (CALM)
Error: symbol '560._translate' is undefined or out of scope.
It looks like those aren't defined in the file. If they're in another assembly file then they need to say "extern" before them instead.
I'll look over the code a bit more and try to resolve the issue
Have you taken a look at the documentation how to link assembly routines to your C code?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement