Quote from: Nightcrawler
Ok.. whew.. let's start with this. If you get a good grasp on the VWF concept, your buffer size matters not. You can work with a 8x16, 16x16 space, 32x16 etc.. and the code will be virtually the same. Your goal in theory is to keep pumping out letters to your buffer until your reach the end. Then transfer to VRAM, start filling up the buffer again, BUT the buffer must start with the 'spill over' of the previous buffer.
Let's start with an easy example. Let's use a simple 8x16 buffer. We want to print 'Time' on the screen. 'T 'is 6 pixels long and 'i' is 3 pixels long.
This is the beginning of the text window, so your buffer must be clear and there is no 'spillover' to print. Now you want to print your 6 pixel wide 'T'. So pound out those 16 bytes(assuming 1bp font). The key to a VWF is to keep track of your pixel/buffer position. We've printed a T.. We didn't fill up the 8x16 buffer yet, so do NOT send to VRAM. We mark we're on pixel 6 and call up the next letter..
It's now time to print 'i'. Oh nuts! we only have 2 width pixels left in our 8 pixel wide buffer, and 'i' is 3 pixels!! What do we do?
We take our data for 'i'.. and shift each byte 6 pixels to the right. Here's tricky part number 2. You must 'catch' the 'spillover'. After shifting the 'i' data 6 bits over, you only have two bits of the 'i' data and the rest are 0's. One way to 'catch' the 'spillover' is to use all 16-bits of the accumulator. You have the low byte clear and high byte contains your 'i' data. Now switch to 16-bit mode and shift right 6 times. Now the high byte has the first two pixels data of 'i' and the low byte contains your 'spillover'.. or the last pixel of the total 3 you had for 'i'.
SO... now you will OR your high byte data with your buffer location which had the 'T'. Because you shifted the 'i' data by 6.. and 'T' only had 6 pixels worth, your can combine the 'i' data with 'T' data and not mess anything up. They will combine nicely. NOW you have a full buffer with 8 pixels of valid data.
Send it to VRAM!
NOW.. the last tricky part is the start of filling up the buffer again. Before you call a new letter, you need to take care of the one pixel 'spillover' from our 'i'. All you do is recall the low byte result you had from our 16-bit shifting and slap that in our buffer.
Now.. you call the next letter.. 'm'.. and you shift that 1 pixel.. OR it with the 'i' data we just posted and repeat.. Say 'm' is only 6 bits long. Now you combined one pixel of 'i' and 6 pixels of 'm', now you're on pixel position 7.... Buffer isn't full yet. Call another letter! Now your 'e' will be shifted 7 times, so you'll only actually put ONE pixel of data in your OR and the rest will be spillover for next time! Transfer to VRAM.
Then you just keep repeating over and over! Be sure to make some sort of trap for control codes though!! Say our 'm' was a control code.. you better have some code to dump out of your routine when that happens rather than try and add it to the buffer!
So, you see.. it doesn't matter if your buffer is 8 pixels, 16 pixels, or 32 pixels wide, you do the same thing. Keep calling letters until it's full. Then transfer to VRAM and remember your 'spillover' at the start of each buffer.
Let's start with an easy example. Let's use a simple 8x16 buffer. We want to print 'Time' on the screen. 'T 'is 6 pixels long and 'i' is 3 pixels long.
This is the beginning of the text window, so your buffer must be clear and there is no 'spillover' to print. Now you want to print your 6 pixel wide 'T'. So pound out those 16 bytes(assuming 1bp font). The key to a VWF is to keep track of your pixel/buffer position. We've printed a T.. We didn't fill up the 8x16 buffer yet, so do NOT send to VRAM. We mark we're on pixel 6 and call up the next letter..
It's now time to print 'i'. Oh nuts! we only have 2 width pixels left in our 8 pixel wide buffer, and 'i' is 3 pixels!! What do we do?
We take our data for 'i'.. and shift each byte 6 pixels to the right. Here's tricky part number 2. You must 'catch' the 'spillover'. After shifting the 'i' data 6 bits over, you only have two bits of the 'i' data and the rest are 0's. One way to 'catch' the 'spillover' is to use all 16-bits of the accumulator. You have the low byte clear and high byte contains your 'i' data. Now switch to 16-bit mode and shift right 6 times. Now the high byte has the first two pixels data of 'i' and the low byte contains your 'spillover'.. or the last pixel of the total 3 you had for 'i'.
SO... now you will OR your high byte data with your buffer location which had the 'T'. Because you shifted the 'i' data by 6.. and 'T' only had 6 pixels worth, your can combine the 'i' data with 'T' data and not mess anything up. They will combine nicely. NOW you have a full buffer with 8 pixels of valid data.
Send it to VRAM!
NOW.. the last tricky part is the start of filling up the buffer again. Before you call a new letter, you need to take care of the one pixel 'spillover' from our 'i'. All you do is recall the low byte result you had from our 16-bit shifting and slap that in our buffer.
Now.. you call the next letter.. 'm'.. and you shift that 1 pixel.. OR it with the 'i' data we just posted and repeat.. Say 'm' is only 6 bits long. Now you combined one pixel of 'i' and 6 pixels of 'm', now you're on pixel position 7.... Buffer isn't full yet. Call another letter! Now your 'e' will be shifted 7 times, so you'll only actually put ONE pixel of data in your OR and the rest will be spillover for next time! Transfer to VRAM.
Then you just keep repeating over and over! Be sure to make some sort of trap for control codes though!! Say our 'm' was a control code.. you better have some code to dump out of your routine when that happens rather than try and add it to the buffer!
So, you see.. it doesn't matter if your buffer is 8 pixels, 16 pixels, or 32 pixels wide, you do the same thing. Keep calling letters until it's full. Then transfer to VRAM and remember your 'spillover' at the start of each buffer.
Original post can be found here.