FAQ  •  Register  •  Login

InLine ASM Bug

<<

LCD

Posts: 507

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Thu May 27, 2010 11:23 pm

InLine ASM Bug

I have here a Assembly code for Proportional printing (Created by Odin), but zxb throws it out because of a "Unexpected token '-' [MINUS]" at the line "DJNZ Chr_R2Lp2". The compiler tells me the line, but a minus sign is not present here (this is the bug report). Anyway, this could be turned by our friends here into a nice SUB for the library, once it works, I think. It supports pixel precise printing.
I imported it from Tornado source code using my own importer, I wrote for BorIDE.
  Code:
Asm
; --------------------------------
;  Free Size N Place Text Print
; --------------------------------
; (c) 14.09.2002 C.Odenthal
;
; Last Modifications: 15.10.2002
; --------------------------------
; ORG 32000
; DUMP 45000
; --------------------------------
; Entry point
; --------------------------------
Start:
   JR Start2
; --------------------------------
; Parameter
; --------------------------------
text_addr:
   DEFW test_text ; Addr of text
x_pos:
   DEFB 4 ; Pos of text
y_pos:
   DEFB 4
spc_size:
   DEFB 3 ; Width of space char
x_gap:
   DEFB 1 ; Gap between chars
y_gap:
   DEFB 1 ; Gap between lines
end_symb:
   DEFB 0 ; End of line char code
x_start:
   DEFB 0 ; Start of window
y_start:
   DEFB 0
x_end:
   DEFB 255 ; End of window
y_end:
   DEFB 191
x_zoom:
   DEFB 1 ; Zooming factor
y_zoom:
   DEFB 1
; --------------------------------
; Main routine
; --------------------------------
Start2:
   LD A,(x_pos); Calc. scr addr.
   LD B,A
   LD A,(y_pos)
   LD C,A
   CALL PosToScr
   LD (scr_ad),DE ; Store scr addr.
   LD A,L
   LD (pix_pos),A
   LD A,(end_symb); Get line ending char
   LD (poke_here+1),A ; Poke it into memory below
   LD HL,(text_addr)
Main_Loop:
   LD A,(HL); Get char
poke_here:
   CP 0 ; End of text? (poked!)
   JP Z,Exit1
   INC HL
   PUSH HL
   CP 32 ; Replace ctrl chars
   JP NC,No_Ctrl
   LD A,32
No_Ctrl:
   CALL Copy_Chr ; Copy char-gfx to work-buffer
   CALL Measure ; Measure left rim + width
   PUSH BC ; (Save results)
   LD A,C ; No pixel set in char?
   AND A
   JP Z,Space_Chr
   LD A,(pix_pos); size+bitpos (=1..15)
   ADD A,C
   CP 9 ; > 8 ?
   JP NC,Overlap ; Char overlaps
; Calculate 8 bit rotation
   LD A,(pix_pos) ; bitpos-l_rim (=-7..7)
   SUB B
   AND A ; = 0 ?
   JP Z,PrintIt8
   JP C,Neg_8 ; < 0 ?
; --------------------------------
   CP 5 ; Not in 1..4 ?
   JP NC,Left_8
; --------------------------------
   LD B,A
   CALL Chr_Rgt8 ; Rotate right 8 bit
   JP PrintIt8
; --------------------------------
Left_8:
   NEG ; = 8 - A
   ADD A,8
   LD B,A
   CALL Chr_Left8 ; Rotate left 8 bit
   JP PrintIt8
; --------------------------------
Neg_8:
   NEG
   CP 5 ; Not in 1..4 ?
   JP NC,Right_8
; --------------------------------
   LD B,A
   CALL Chr_Left8 ; Rotate left 8 bit
   JP PrintIt8
; --------------------------------
Right_8:
   NEG ; = 8 - A
   ADD A,8
   LD B,A
   CALL Chr_Rgt8 ; Rotate right 8 bit
   JP PrintIt8
; --------------------------------
; Calculate 16 bit rotation
; --------------------------------
Overlap:
   LD A,(pix_pos); bitpos-l_rim (=-7..7)
   SUB B
   AND A ; = 0 ?
   JP Z,PrintIt8
; --------------------------------
   LD B,A
   CALL Chr_Rgt16 ; Rotate right 16 bit
PrintIt16:
   LD DE,(scr_ad); Check for screen end
   LD A,E
   AND 31
   CP 31 ; (2nd byte outside ?)
   JP Z,Outside
   CALL Print16 ; Display char (16 bit)
   JP Next_Loc
; --------------------------------
PrintIt8:
   LD DE,(scr_ad); Display char (8 bit)
   CALL Print8
   JP Next_Loc
; --------------------------------
Space_Chr:
   LD A,(spc_size); Skip pixels
   LD DE,(scr_ad); Get screen addr.
   POP BC ; Throw away values
   LD B,0
   LD C,A
   JP Next_Loc2
; --------------------------------
Next_Loc:
   POP BC ; Move to next char location
Next_Loc2:
   LD A,(pix_pos); =bitpos+x_gap+size
   LD L,A
   LD A,(x_gap)
   ADD A,L
   ADD A ,C
   LD L ,A
   AND 7 ; New pix_pos
   LD (pix_pos),A
   LD H,0 ; =result/8
   SRL L
   SRL L
   SRL L
   ADD HL,DE ; New byte pos
   LD A ,E ; Check for screen end
   AND 31
   LD E,A
   LD A,L
   AND 31
   CP E ; New pos smaller than old ?
   JP C ,Exit2 ; -> End of printing
   LD (scr_ad),HL ; Store new scr ad.
   POP HL ; Restore text pointer
   JP Main_Loop
; --------------------------------
Outside:
   POP BC ; Stop printing
   POP HL ; Char not printed!
   DEC HL
   JP Exit1
; --------------------------------
Exit2:
   POP HL ; Return nr of printed chars
Exit1:
   LD DE,(text_addr)
   XOR A
   SBC HL,DE
   LD B,H ; Return value in BC to Basic
   LD C,L
   RET
; --------------------------------
; --------------------------------
; Calc. scr adr from x,y
; --------------------------------
; In : B  = x / C = y (preserved)
; Out: DE = scr adr / L = pixpos
; Usd: A, BC, DE, L
; --------------------------------
PosToScr:
   LD A,C ; Range check
   CP 185
   JP C,ValOk
   LD C,184
ValOk:
   LD A,B ; Pix pos
   AND 7
   LD L,A
   LD E,B
   SRL E
   SRL E
   SRL E
   LD A,C ; Scr pos
   AND 7
   LD D,A
   LD A,C
   AND 56
   RLA
   RLA
   OR E
   LD E,A
   LD A,C
   AND 192
   RRA
   RRA
   RRA
   OR D
   OR 64
   LD D,A
   RET
; --------------------------------
; Copy char into buffer
; --------------------------------
; In : A = Char
; Out: -
; Usd: A, HL, DE, BC
; --------------------------------
Copy_Chr:
   LD DE,(23606); SysVar CHARS
   LD H,0
   LD L,A
   ADD HL,HL ; * 8
   ADD HL,HL
   ADD HL,HL
   ADD HL,DE ; + Chartable
   EX DE,HL
   LD HL,Chr_Buf
   LD B,8
Copy_Loop:
   LD A,(DE); Double to 16 pixel/row
   INC DE
   LD (HL),A ; Low-byte in memory!
   INC HL
   LD (HL),0 ; High-byte in memory!
   INC HL
   DJNZ Copy_Loop
   RET
; --------------------------------
; Measure left border and width
; --------------------------------
; In : -
; Out: B = left rim / C = width
; Usd: A, HL, BC
; --------------------------------
Measure:
   LD HL,Chr_Buf ; "OR" together all 8 bytes
   LD B,8
   XOR A
Msr_Loop:
   OR (HL)
   INC HL
   INC HL
   DJNZ Msr_Loop
   LD BC,0
   AND A ; Check if zero
   RET Z
Msr_Loop2:
   INC B ; Measure left border
   RLCA
   JP NC,Msr_Loop2
   RRCA
   DEC B
   LD C,9 ; Measure width
Msr_Loop3:
   DEC C
   RRCA
   JP NC,Msr_Loop3
   RET
; --------------------------------
; Move char to left, 8 bit
; --------------------------------
; In : B = Nr of bits to shift
; Out: -
; Usd: A, B, HL
; --------------------------------
Chr_Left8:
   PUSH BC
   LD HL,Chr_Buf ; Rotate char left 8 bit
   LD C,B ; 1st row
   LD A,(HL )
Chr_LLp1:
   RLCA
   DJNZ Chr_LLp1
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 2nd row
   LD A,(HL)
Chr_LLp2:
   RLCA
   DJNZ Chr_LLp2
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 3rd row
   LD A ,(HL)
Chr_LLp3:
   RLCA
   DJNZ Chr_LLp3
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 4th row
   LD A,(HL)
Chr_LLp4:
   RLCA
   DJNZ Chr_LLp4
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 5th row
   LD A,(HL)
Chr_LLp5:
   RLCA
   DJNZ Chr_LLp5
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 6th row
   LD A,(HL)
Chr_LLp6:
   RLCA
   DJNZ Chr_LLp6
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 7th row
   LD A,(HL)
Chr_LLp7:
   RLCA
   DJNZ Chr_LLp7
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 8th row
   LD A,(HL)
Chr_LLp8:
   RLCA
   DJNZ Chr_LLp8
   LD (HL),A
   LD B,C
   POP BC
   RET
; --------------------------------
; Move char to right, 8 bit
; --------------------------------
; In : B = Nr of bits to shift
; Out: -
; Usd: A, B, HL
; --------------------------------
Chr_Rgt8:
   PUSH BC
   LD HL,Chr_Buf ; Rotate char right 8 bit
   LD C,B ; 1st row
   LD A,(HL)
Chr_RLp1:
   RRCA
   DJNZ Chr_RLp1
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 2nd row
   LD A,(HL)
Chr_RLp2:
   RRCA
   DJNZ Chr_RLp2
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 3rd row
   LD A,(HL)
Chr_RLp3:
   RRCA
   DJNZ Chr_RLp3
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 4th row
   LD A,(HL)
Chr_RLp4:
   RRCA
   DJNZ Chr_RLp4
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 5th row
   LD A,(HL)
Chr_RLp5:
   RRCA
   DJNZ Chr_RLp5
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 6th row
   LD A ,(HL )
Chr_RLp6:
   RRCA
   DJNZ Chr_RLp6
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 7th row
   LD A,(HL)
Chr_RLp7:
   RRCA
   DJNZ Chr_RLp7
   LD (HL),A
   LD B,C
   INC HL
   INC HL
   LD C,B ; 8th row
   LD A,(HL)
Chr_RLp8:
   RRCA
   DJNZ Chr_RLp8
   LD (HL),A
   LD B,C
   POP BC
   RET
; --------------------------------
; Move char to right 16 bit
; --------------------------------
; In : B = Nr of bits to shift
; Out:
; Usd: A, B, HL
; --------------------------------
Chr_Rgt16:
   LD HL,(Chr_Buf); Rotate char right 16 bit
   LD A,B ; 1st row
Chr_R2Lp1:
   SRL L
   RR H ; Insert carry
   DJNZ Chr_R2Lp1
   LD B,A
   LD (Chr_Buf),HL
   LD HL,(Chr_Buf+2); 2nd row
   LD A,B
Chr_R2Lp2:
   SRL L
   RR H ; Insert carry
   DJNZ Chr_R2Lp2
   LD B,A
   LD (Chr_Buf+2),HL
   LD HL,(Chr_Buf+4); 3rd row
   LD A,B
Chr_R2Lp3:
   SRL L
   RR H ; Insert carry
   DJNZ Chr_R2Lp3
   LD B,A
   LD (Chr_Buf+4),HL
   LD HL,(Chr_Buf+6); 4th row
   LD A,B
Chr_R2Lp4:
   SRL L
   RR H ; Insert carry
   DJNZ Chr_R2Lp4
   LD B,A
   LD (Chr_Buf+6),HL
   LD HL,(Chr_Buf+8); 5th row
   LD A,B
Chr_R2Lp5:
   SRL L
   RR H ; Insert carry
   DJNZ Chr_R2Lp5
   LD B,A
   LD (Chr_Buf+8),HL
   LD HL,(Chr_Buf+10); 6th row
   LD A,B
Chr_R2Lp6:
   SRL L
   RR H ; Insert carry
   DJNZ Chr_R2Lp6
   LD B,A
   LD (Chr_Buf+10),HL
   LD HL,(Chr_Buf+12); 7th row
   LD A,B
Chr_R2Lp7:
   SRL L
   RR H ; Insert carry
   DJNZ Chr_R2Lp7
   LD B,A
   LD (Chr_Buf+12),HL
   LD HL,(Chr_Buf+14); 8th row
   LD A,B
Chr_R2Lp8:
   SRL L
   RR H ;Insert carry
   DJNZ Chr_R2Lp8
   LD B,A
   LD (Chr_Buf+14),HL
   RET
; --------------------------------
; Print 8 bit wide char on screen
; --------------------------------
; In : DE = screen adr.
; Out: -
; Usd: A, HL, DE, B
; --------------------------------
Print8:
   LD HL,Chr_Buf
   PUSH DE ; save scr ad.
   EX DE,HL
   LD B,8 ; 8 lines
Prt8_L:
   LD A,(DE); set 1 byte
   XOR (HL)
   LD (HL),A
   INC DE ; skip 1 byte
   INC DE ; next byte
   INC H ; calc. next line
   LD A,H
   AND 7
   JP NZ,Prt8_C
   LD A,L
   ADD A,32
   LD L,A
   JR C,Prt8_C
   LD A,H
   SUB 8
   LD H,A
Prt8_C:
   DJNZ Prt8_L ; next round
   POP DE ; restore scr ad.
   RET
 --------------------------------
; Print 16 bit wide char on screen
; --------------------------------
; In : DE = screen adr.
; Out: -
; Usd: A, HL, DE, B
; --------------------------------
Print16:
   LD HL,Chr_Buf
   PUSH DE ; save scr ad.
   EX DE,HL
   LD B,8 ; 8 lines
Prt16_L:
   LD A,(DE); set 1 byte
   XOR (HL)
   LD (HL),A
   INC HL ; next scr pos
   INC DE ; next byte
   LD A,(DE); set 1 byte
   XOR (HL)
   LD (HL),A
   DEC HL ; prev scr pos
   INC DE ; next byte
   INC H ; calc. next line
   LD A,H
   AND 7
   JP NZ,Prt16_C
   LD A,L
   ADD A,32
   LD L,A
   JR C,Prt16_C
   LD A,H
   SUB 8
   LD H,A
Prt16_C:
   DJNZ Prt16_L ; next round
   POP DE ; restore scr ad.
   RET
; --------------------------------
;  Variables
; --------------------------------
Chr_Buf:
   DEFS 16
scr_ad:
   DEFW 0
pix_pos:
   DEFB 0
test_text:
   DEFM "This is a test for proportional print!"
   DEFB 0,0
; --------------------------------
end asm
Last edited by LCD on Fri May 28, 2010 6:09 pm, edited 1 time in total.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

britlion

Posts: 679

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Fri May 28, 2010 4:21 am

Re: InLine ASM Bug

Even though it reports the error in line 474, actually the problem is in line 559:

  Code:
--------------------------------
; Print 16 bit wide char on screen
; --------------------------------


You forgot the ; at the start of the dashes.


ZX BASIC doesn't work out line numbers in ASM sections well - it ignores comments, so you have to add on for each of the comment lines above it to get the right number. I've bugged this before. As a workaround, in ASM sections, when I can't find the problem like this, I insert a dummy code like "LD F,G" at the line it says, and then it tells me what line it THINKS that is, and I get an idea how much farther down to look. A few tries of that dummy opcode, and you find the line it means.
<<

boriel

Site Admin

Posts: 1147

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Fri May 28, 2010 7:31 am

Re: InLine ASM Bug

britlion wrote:ZX BASIC doesn't work out line numbers in ASM sections well - it ignores comments, so you have to add on for each of the comment lines above it to get the right number. I've bugged this before. As a workaround, in ASM sections, when I can't find the problem like this, I insert a dummy code like "LD F,G" at the line it says, and then it tells me what line it THINKS that is, and I get an idea how much farther down to look. A few tries of that dummy opcode, and you find the line it means.

That's right. I will work on it MUCH later. Meanwhile, use the #line directive (It's a very standard directive).

  Code:
...
...
; Next line resets linecounter to 372
#line 372
sdafasdffasfa ; Syntax error at line 372


You can also specify a diferent file name. So
#line 372 "newfile.bas"
will not only change the line counter, but the supposed filename in the error messages.

This is a standard directive in many compilers: http://msdn.microsoft.com/en-us/library ... 80%29.aspx

ZX Basic already put #line directives on the fly during file includes (that's what most compilers do, BTW). But when inlining ASM it stil does not. Needs to be fixed.
<<

LCD

Posts: 507

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Fri May 28, 2010 2:35 pm

Re: InLine ASM Bug

Thanks! Indeed I must have accidentialy deleted the ";" after conversion.
Anyway, #Line directive added to wordlist of BorIDE
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

britlion

Posts: 679

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Tue Jun 01, 2010 12:31 pm

Re: InLine ASM Bug

Note that #line doesn't seem to work inside asm blocks (where it might be more useful!)

Can use

end asm
#line <num>
asm

pretty easily though. I sometimes do that just same trick so basic has a label to access into the machine code...
<<

boriel

Site Admin

Posts: 1147

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Tue Jun 01, 2010 5:48 pm

Re: InLine ASM Bug

britlion wrote:Note that #line doesn't seem to work inside asm blocks (where it might be more useful!)

It MUST. You have discovered a bug :!: since even #include "xxx.asm" is not working. I'm fixing it.

Return to Bug Reports

Who is online

Users browsing this forum: No registered users and 1 guest

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO