Page 2 of 3

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Wed Jun 26, 2013 12:15 pm
by peacer
So according to wiki, I need to use Zero Page Indirect Indexed with Y: (zp),y instead of Zero Page Indexed with X: zp,x. I will think of that.

About adding number to 2 byte memory , what could be fastest and shortest code?

To simplify the question , what could be easiest machine code counterpart of "DOKE N,DEEK(N)+40" ?

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Wed Jun 26, 2013 1:33 pm
by Chema
Using the same idea, simply:

Code: Select all

  
   lda N
   clc
   adc #40
   sta N
   bcc nocarry1
   inc N+1
nocarry1
  ...
Which means, instead of loading the contents of N+1,adding 0 plus the carry and storing the result, check if carry is clear and, if not so, increment the contents of N+1, or else branch over the instruction. This works because the high byte of 40 is zero, of course.

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Wed Jun 26, 2013 3:47 pm
by peacer
Thanks :)

But You said "This works because the high byte of 40 is zero" . Actually we are increasing it #28 not #40 as 40 is decimal for character number per line. Does it matter?

Or maybe I misunderstood and #40 means 40 in decimal, not hexadecimal?

I think I am thinking in BASIC not machine code :) Is it true such as : #40 --> decimal and #$40 hexadecimal?

You know, In basic #40 describes hexadecimal value.

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Wed Jun 26, 2013 5:53 pm
by Chema
Yep, lda #40 loads 40 in decimal, not hex, into the accumulator in immediate addressing mode. That is what the # means, inmediate addressing. $ is used to denote hexadecimal numbers.

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Wed Jun 26, 2013 8:00 pm
by peacer
:) I learn new things everyday

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Thu Jun 27, 2013 11:46 pm
by peacer
How can we control 6th bit after shifting the byte to the left.

BIT command is supposed to check 6th and 7th bits but I couln't visualise usage in my mind.

I plan to use it this way :

1- Clear Carry
2- Read last byte of the scrolling line and transfer it to Accumulator.
3- ASL the accumulator.
4- With using BIT command check if 6th bit is set or not.
5- If 6th bit is on after ASL, set carry as 1 and accumulator is corrected with AND 63 to clear 6th bit again.
6- Write accumulator to the same byte.
7- Pass to the byte left to the first one and do the steps 2 and 3
8- Increase accumulator with carry so bit is transferred from the byte on the right
9 -Clear carry again and do the steps 4,5,6 until reaching to the first byte on the line.
10-Go to next line and do the same things again for required times.
11-Draw last bit of every line for continuation of scrolling and do the scroll again.

This is the plan :)
I think I can handle all the steps but I couldn't imagine how BIT command operates. BIT has zero page absolute operands. So

- Write Accumulator on a zero page location
- BIT command on that location
- Using BVC (Branch on Overflow) so whether decide to run step 5 or not.

Do you think this worksheet is ok?

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Thu Jun 27, 2013 11:52 pm
by Dbug
In the assembly 2002 demo, the scroller at the top is done this way:

Code: Select all

	ldx #0
ScrollerDisplayLoopMessageY
	; Get pixel from character
	clc
	lda ScrollerCharBuffer,x
	rol
	cmp #192
	and #$3F
	ora #64
	sta ScrollerCharBuffer,x

	; And then scroll the whole scanline
	ldy #38
ScrollerDisplayLoopMessageX
	lda (tmp6),y
	rol
	cmp #192
	and #%00111111
	ora #%01000000
	sta (tmp6),y

	dey
	bne ScrollerDisplayLoopMessageX
Full source code is there: http://miniserve.defence-force.org/svn/ ... scroller.s

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Fri Jun 28, 2013 12:22 am
by peacer
:) need to understand the code. Thanks.

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Fri Jun 28, 2013 11:18 am
by Chema
It is a simple and brilliant idea.

The problem is due to the six-bit per byte display on the Oric. The contents of the screen are represented by only the 6 lower bits of the byte, while the 7th bit (numbering them as 76543210) must be 0 (to indicate not inverse mode) and the 6th must be 1 (to indicate that this is not an attribute).

Therefore we should make sure to keep bits 6 and 7 unmodified and also make sure that, when rotating, it is the 5th bit which we are shifting into the carry, so it ends up in the lowest bit of the next scan. A rotate left operation won't work, as it will shift bit 7 into the carry, not bit 5.

How can we do this, then? Let's see:

At every loop you get the byte and rotate it to the left (shifting the value in the carry into the lowest bit). Then you compare the result with the number 192, which is 11000000 in binary. This will set the carry only if the value of the 5th bit was 1 before the rotation. Notice that every screen byte already has the 6th bit set, to indicate it is not an attribute.

So, a byte such as 01010000 (which represents a pattern of screen pixels 010000), after the rotation will become 10100000, less than 192 and after the comparison the carry will be clear. On the other hand a byte such as 01100000 (a pattern of 100000), will become after the rotation 11000000, so the carry will be set after the comparison.

This way you shift the correct pixel value (contained if the carry) onto the next screen scan. The only thing left is fixing the value after the rotation so its 7th bit is set to 0 and its 6th bit is set to 1 (no inverse and no attribute). Therefore the and operation with the mask 00111111 and the ora operation with the value 01000000.

Code: Select all

Original screen value |  Carry before the rotation | After rotation to the left | Carry after comparison | After fixing by AND/ORA
01010000                        0                                 10100000                         0                       01100000
01100000                        0                                 11000000                         1                       01000000
Mmmm... re-reading this I am not sure if I made myself clear, but it is quite simple once you get the general idea.

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Fri Jun 28, 2013 6:42 pm
by peacer
Trying to comprehend :) Thanks.

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Fri May 18, 2018 7:12 am
by ibisum
Hi @peacer - did you eventually get this working such that you have a generalised method of scrolling HIRES regions? I'd sort of have a use for that myself right now, in case you did ..

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Fri May 18, 2018 9:13 am
by Dbug
HIRES scrolling is generally a very context specific operation, and ultimately it depends on a number of factors:
- How much memory are your willing to use
- Do you need to scroll the entire HIRES screen
- Does the scroll area contains attributes or not
- Do you use some backbuffer (or work directly on the screen)
- Do you need pixel accurate shift or is 2 or 3 pixel accuracy good enough
- Are you scrolling some arbitrary bitmaps, or some tile-based map that is render into HIRES
- Do you use video inversion
- Do you have sprites, and do they use masking/xor
etc...

I don't think I've reused the exact same HIRES scrolling routine twice in my games or demos

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Fri May 18, 2018 4:41 pm
by peacer
ibisum wrote: Fri May 18, 2018 7:12 am Hi @peacer - did you eventually get this working such that you have a generalised method of scrolling HIRES regions? I'd sort of have a use for that myself right now, in case you did ..
Unfortunately no :shock:

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Tue May 22, 2018 3:55 pm
by ThomH
If you could afford a 64-byte lookup table where the value at binary offset `abcdef` is `a01bcdef` and the use of all three registers then you can shave two cycles over the explicit cmp/and/ora:

Code: Select all

    LDX line, Y     	; load current pixel contents into X; guaranteed to be of the form '01ab cdef'
    LDA table-64, X	; use table to map that to 'a01b cdef'
    ROL			; rotate to '01bc defx', with the top pixel going into carry and the prior top pixel coming out of carry
    STA line, Y		; store
Though I think even the best unrolling of that sufficiently to target the whole display* costs at least 13kb and still doesn't reach 9 fps. So probably just write an ordinary loop and scroll more selectively.

* 10 bytes per iteration, assuming `line` is adjusted between iterations, is 400 for "a line" but that could only ever reach columns within 256 bytes of the start of video memory, so have 30 versions of that. Plus the 64-byte lookup table, plus the outer logic. Actually I guess you could shave a bit more than a kilobyte by putting the lookup table into the zero page, but it wouldn't make things faster and you'd lose a quarter of the zero page.

Re: Horizontal HIRES and Text scrolling code needed.

Posted: Tue May 22, 2018 4:06 pm
by ibisum
Very fascinating technique, I must admit.

What I want to do right now is just scroll the top 64 lines of a HIRES screen, plain ol' demo style.. actually I've changed up the 'requirements' a bit too and really its just about applying any kind of effects of a 240x64 line of graphics, which serve as the header of a text-file that fills the rest of the screen .. I've been grok'ing and grep'ing around a bit of the code of the pro's, and its really interesting the plethora of techniques for doing things.

Still haven't got something quite working yet, but mostly only because I'm still working through OSDK MacOS toolchain issues, for now .. but I'll probably come back to this bit-table method and implement a naive hack as soon as I have the C/Assembly thing worked out, tools-wise.