Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
InLine ASM Bug
#1
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
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#2
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.
Reply
#3
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: <!-- m --><a class="postlink" href="http://msdn.microsoft.com/en-us/library/b5w2czay%28VS.80%29.aspx">http://msdn.microsoft.com/en-us/library ... 80%29.aspx</a><!-- m -->

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.
Reply
#4
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!
Reply
#5
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...
Reply
#6
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.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)