Jump to content
IGNORED

Kernel request thread


vdub_bobby

Recommended Posts

batari and vdub, how goes integration of the multi-sprite kernel into bB?  Or that process in a state where there's no guessing how long it may or may not take?  (Not trying to be a pest, just very interested to see it  :)  )

951911[/snapback]

The issue is with memory organization. In the old kernel, the compiler could place sprite data almost anywhere in the .bin, but the new kernel requires careful organization of sprite data, which is hard to do automatically without wasting ROM space if there are more than a certain number of sprite graphics defined. Basically, the new kernel requires that for every 160 bytes of sprite data, there needs to be 96 bytes of space. You can put other stuff here, but not graphics.

 

I haven't come up with solutions to this problem that don't also require compromises. Generating a heavily obfuscated .asm file (or lots of separate .asm files) may help to reduce waste by trying to put code or data in the 96 byte segments, but it would also make it harder for someone wanting to learn assembly to understand it. One of my goals with bB was to help people learn assembly by reading the .asm file, so I want to keep it readable by human eyes.

 

Another option is to require relocatable modules to include a comment at the beginning that includes the size of the module, because bB has no way of knowing their size beforehand - only DASM can do this. Then bB could put the small modules in these 96 byte segments. However, I do not really like this idea- I want something that can be done automatically instead of requiring people to always manually add the compiled size of each module (which is really easy to get wrong!)

 

So basically I've been languishing over this problem since I don't have a good solution, and not working on bB very much. But now that you bring up the kernel again, I think it may be a good idea to go ahead and ignore the issue entirely, letting the compiler be a little wasteful on space and optimize it at some later release. But at the same time, if I allow an option to build 8k bankswitched binaries, it will mitigate the waste issues somewhat. I have figured out how to do the bankswitching, so there's no dilemma here.

 

Well, I also want to finish the Space Invaders clone too :)

Link to comment
Share on other sites

Ah, I can see how it's been a quandry!

 

But now that you bring up the kernel again, it may be a good idea to go ahead and ignore the issue entirely, letting the compiler be a little wasteful on space and optimize it at some later release.  But at the same time, if I allow an option to build 8k bankswitched binaries, it will mitigate the waste issues somewhat.  I have figured out how to do the bankswitching, so there's no dilemma here.

 

:thumbsup: I concur, that does sound like a good idea, especially with a bankswitching option to compensate for some of the wastefulness. Plus, once it's "out there", members of the community may have additional clever ideas about how to help with optimization.

 

Well, I also want to finish the Space Invaders clone too :)

952490[/snapback]

 

Whoo hoo! :D And thanks for the update. :)

Link to comment
Share on other sites

  • 3 weeks later...

vdub, can you post the source code from the binary at the top of this thread? It's a pretty neat little demo and I would like to play around with it a little. Thanks.

 

-JD

 

Oh, another question for you guys, what causes the black lines at the left of the screen? Is this the same thing that sometimes causes the top scan line to not start on time, and can it be fixed?

Edited by MayDay
Link to comment
Share on other sites

vdub, can you post the source code from the binary at the top of this thread?  It's a pretty neat little demo and I would like to play around with it a little.  Thanks.

 

-JD

Sure. I'll attach two versions; one will compile to the posted demo, the other will compile to a different demo, using the same kernel, that I was working on.

Oh, another question for you guys, what causes the black lines at the left of the screen?  Is this the same thing that sometimes causes the top scan line to not start on time, and can it be fixed?

The black lines show up (almost) every time you reposition a sprite in the middle of the screen. There are some limited, tricky ways to get rid of them, though not with bBASIC as it currently stands.

bbk1.zip

Edited by vdub_bobby
Link to comment
Share on other sites

It strikes mine... is the source available? Since you've already posted in my Dragon Warrior thread, I'm guessing you know my intentions! :) (and if not, you should now). As I said, it will be quite a while before I start this, but thought I would ask while the thread is fresh.

 

Thanks,

JD

 

PS- I've been studying the code from that demo I asked for, and I must say it's quite impressive. I have one question though, are the numbers to the right of your code that are commented during the kernel a timing count or something else? I also think your spaceship code is very well suited for this if you were interested in adding to it (and they would bless it).

Link to comment
Share on other sites

It strikes mine... is the source available?  Since you've already posted in my Dragon Warrior thread, I'm guessing you know my intentions! :)  (and if not, you should now).  As I said, it will be quite a while before I start this, but thought I would ask while the thread is fresh.

 

Thanks,

JD

 

PS- I've been studying the code from that demo I asked for, and I must say it's quite impressive.  I have one question though, are the numbers to the right of your code that are commented during the kernel a timing count or something else?  I also think your spaceship code is very well suited for this if you were interested in adding to it (and they would bless it).

966865[/snapback]

Yeah, they're a timing count - very important in 2600 kernels!

 

As for the source to the text demo I just posted...well, sure. It isn't my best work - well, actually, it mostly isn't my work at all :P

 

I ripped off the character set and the kernel from Basic Programming.

 

Here ya go:

TextKernelbB.zip

Link to comment
Share on other sites

As for the source to the text demo I just posted...well, sure.  It isn't my best work - well, actually, it mostly isn't my work at all :P

 

I ripped off the character set and the kernel from Basic Programming.

 

Here ya go:

966886[/snapback]

I've got this on the agenda for the next release. So one will actually be able to do:

 

10 print "Hello, World!"

20 goto 10

 

I was thinking, though, since the RAM previously used for the playfield and the sprite pointers will be free, it should be possible to have a couple of string variables too. Maybe two strings, each 12 chars long.

 

a$="HELLO, ":if joy0right then a$(7)="FRED" else a$(7)="BOB"

print a$

 

Would it just be a simple matter of setting some pointers to point to RAM? I guess I'll know better when I finally get a change to dig into bB again in a few weeks.

Link to comment
Share on other sites

Hi Batari,

 

With the new sprite kernel, could you PLEASE PLEASE add things like:

 

- some kind of var/point to attach 'colordata' to (for background a 192byte array in rom', for sprites a 'spriteheight' array of colors)... which during drawing will be read..... you could do it by having vars like p0colordata=mycolordata

 

if you do p0colordata=14 it will just draw the sprite normally with color 14

otherwise it will draw it using the data in mycolordata and increase colordatapointer each scanline.

 

same goes for the background.....

 

 

P.S. a 'normal' 16-bit var or indexpoint would be extremely helpful. i've got a pretty nifty musicplayer but it only plays for 3 seconds because my data point > 255

 

martijn

Link to comment
Share on other sites

As for the source to the text demo I just posted...well, sure.  It isn't my best work - well, actually, it mostly isn't my work at all :P

 

I ripped off the character set and the kernel from Basic Programming.

 

Here ya go:

966886[/snapback]

I've got this on the agenda for the next release. So one will actually be able to do:

 

10 print "Hello, World!"

20 goto 10

 

I was thinking, though, since the RAM previously used for the playfield and the sprite pointers will be free, it should be possible to have a couple of string variables too. Maybe two strings, each 12 chars long.

 

a$="HELLO, ":if joy0right then a$(7)="FRED" else a$(7)="BOB"

print a$

 

Would it just be a simple matter of setting some pointers to point to RAM? I guess I'll know better when I finally get a change to dig into bB again in a few weeks.

967861[/snapback]

I think that should be doable - you'd just need 12 bytes of RAM for each string. You'd probably have to change the code a little if you wanted to display both text stored in RAM and text stored in ROM at the same time, but it shouldn't be too difficult. Well, on second thought, it might be kinda difficult. :P

Link to comment
Share on other sites

Hi Batari,

 

With the new sprite kernel, could you PLEASE PLEASE add things like:

 

- some kind of var/point to attach 'colordata' to (for background a 192byte array in rom', for sprites a 'spriteheight' array of colors)... which during drawing will be read..... you could do it by having vars like p0colordata=mycolordata

 

if you do p0colordata=14 it will just draw the sprite normally with color 14

otherwise it will draw it using the data in mycolordata and increase colordatapointer each scanline.

 

same goes for the background.....

This would require a completely new kernel, so it isn't likely to happen real soon.

 

If you want multi-colored sprites, you have to give up some other things, like the pseudo-bitmapped playfield, or one or both of the missiles, or the ball, or something.

P.S. a 'normal' 16-bit var or indexpoint would be extremely helpful. i've got a pretty nifty musicplayer but it only plays for 3 seconds because my data point > 255

A var/index that could range from 0 to 65K would be pretty cool alright, but probably would be pretty stinking hard to implement.

 

Of course, you can always get around this by using a dummy variable like so...

 

MusicData0
  10,23,40,50,...,255

When your musicplayer hits the 255 it sets the index back to zero and starts reading from MusicData1 or whatever.

 

Or you could just switch to MusicData1 when your index hits 255.

Link to comment
Share on other sites

QUOTE(superogue @ Fri Nov 18, 2005 12:12 AM)

- some kind of var/point to attach 'colordata' to (for background a 192byte array in rom', for sprites a 'spriteheight' array of colors)... which during drawing will be read..... you could do it by having vars like p0colordata=mycolordata

 

if you do p0colordata=14 it will just draw the sprite normally with color 14

otherwise it will draw it using the data in mycolordata and increase colordatapointer each scanline.

 

same goes for the background.....

 

This would require a completely new kernel, so it isn't likely to happen real soon.

 

If you want multi-colored sprites, you have to give up some other things, like the pseudo-bitmapped playfield, or one or both of the missiles, or the ball, or something.

like i stated before, i have no problems having other things suffered for this. i think it could be setup in a way that it shouldn't affect the current kernel..

in the main kernel file (even if it contains different kernel-handling) check e.g. p0colordata, or bg/pfcolordata if its a number -> use current kernel, if its pointed to data, use different handling.. increasing a pointer each scanline for the bg/p0/p1 shouldn't be that hard to implement (even if you suffer a few cycles and have no missile or ball).

i understand that multiplexing sprites might be a different thing alltogether, but just adding 'coloring' should be very doable imho.

Link to comment
Share on other sites

QUOTE(superogue @ Fri Nov 18, 2005 12:12 AM)

- some kind of var/point to attach 'colordata' to (for background a 192byte array in rom', for sprites a 'spriteheight' array of colors)... which during drawing will be read..... you could do it by having vars like p0colordata=mycolordata

 

if you do p0colordata=14 it will just draw the sprite normally with color 14

otherwise it will draw it using the data in mycolordata and increase colordatapointer each scanline.

 

same goes for the background.....

 

This would require a completely new kernel, so it isn't likely to happen real soon.

 

If you want multi-colored sprites, you have to give up some other things, like the pseudo-bitmapped playfield, or one or both of the missiles, or the ball, or something.

like i stated before, i have no problems having other things suffered for this. i think it could be setup in a way that it shouldn't affect the current kernel..

in the main kernel file (even if it contains different kernel-handling) check e.g. p0colordata, or bg/pfcolordata if its a number -> use current kernel, if its pointed to data, use different handling.. increasing a pointer each scanline for the bg/p0/p1 shouldn't be that hard to implement (even if you suffer a few cycles and have no missile or ball).

i understand that multiplexing sprites might be a different thing alltogether, but just adding 'coloring' should be very doable imho.

968384[/snapback]

The color striping won't be too hard, it's just a matter of implementation into the compiler itself (i.e. before striping occurs, we need new commands to use these features) and, of course, a few different kernels should be in place.

 

As for multiplexing/interlacing, I assume you are talking about flicker, i.e. displaying objects on alternate frames. This may eventually be done automatically for the multisprite kernel if objects overlap, as some code for doing this is publically available. But for a while you'll still need to do this yourself.

Link to comment
Share on other sites

I think that should be doable - you'd just need 12 bytes of RAM for each string.  You'd probably have to change the code a little if you wanted to display both text stored in RAM and text stored in ROM at the same time, but it shouldn't be too difficult.  Well, on second thought, it might be kinda difficult.  :P

968004[/snapback]

I looked into this tonight. It doesn't look too hard, but we will definitely need more RAM to pull it off because of how the character tables are stored (i.e. as a contiguous block of ROM.) Basically, for each line of text, we'd have another pointer for the start of the chars. So with 13 lines, that's 26 more bytes of RAM. But we'd need to do this anyway, since I would like to allow one to put a line of text on any line, or even the same line more than once.

 

I hope that there is still enough for a couple of 12-char strings after this!

 

Also, I think I need to change the way character data is stored. Actually, I have to, since the chars use the labels A-Z, and these are already reserved as variables in bB.

 

What I'd really like to do is store characters in ASCII order, but just use 32-90. Then for a line of text, we'd just need to produce:

.byte "HELLO, WORLD!"

 

Does anyone want to design the missing sprites for ASCII 32-90? The chars appear to be 7x7. If anyone's interested, take a look at the demo to see what we already have first...

 

dec hex char
------------
32 20 SPACE
33 21 !
34 22 "     
35 23 #
36 24 $
37 25 %
38 26 &
39 27 '
40 28 (
41 29 )
42 2A *
43 2B +
44 2C ,
45 2D -
46 2E .
47 2F /
48 30 0
49 31 1
50 32 2
51 33 3
52 34 4
53 35 5
54 36 6
55 37 7
56 38 8
57 39 9
58 3A :
59 3B;
60 3C <     
61 3D =
62 3E >     
63 3F ?
64 40 @    
65 41 A    
66 42 B
67 43 C
68 44 D
69 45 E
70 46 F
71 47 G
72 48 H
73 49 I
74 4A J
75 4B K
76 4C L
77 4D M
78 4E N
79 4F O
80 50 P
81 51 Q
82 52 R
83 53 S
84 54 T
85 55 U
86 56 V
87 57 W
88 58 X
89 59 Y
90 5A Z

Link to comment
Share on other sites

I think that should be doable - you'd just need 12 bytes of RAM for each string.  You'd probably have to change the code a little if you wanted to display both text stored in RAM and text stored in ROM at the same time, but it shouldn't be too difficult.  Well, on second thought, it might be kinda difficult.  :P

968004[/snapback]

I looked into this tonight. It doesn't look too hard, but we will definitely need more RAM to pull it off because of how the character tables are stored (i.e. as a contiguous block of ROM.) Basically, for each line of text, we'd have another pointer for the start of the chars. So with 13 lines, that's 26 more bytes of RAM. But we'd need to do this anyway, since I would like to allow one to put a line of text on any line, or even the same line more than once.

 

I hope that there is still enough for a couple of 12-char strings after this!

Well, if you rewrote the code to have pointers to each line, you could eliminate one of the other variables. Let's see...

13 pointers, each to a line of text = 26 bytes

12 pointers, each to a character on a line = 24 bytes

1 byte (or 1 bit) for a frame counter.

 

That plus a temp variable or two are probably all you would need. You could drop the line counter variable. Of course, you are already up to ~50 bytes! How many bytes are used by the standard kernel for the PF and players/missiles?

Edited by vdub_bobby
Link to comment
Share on other sites

How many bytes are used by the standard kernel for the PF and players/missiles?

969387[/snapback]

 

For Player/missles

8 for x,y pos

4 for player pointers

4 for player/missle height

48 for playfield

1 for playfield scrolling

----

65

 

Ball:

3 additional bytes

Link to comment
Share on other sites

How many bytes are used by the standard kernel for the PF and players/missiles?

969387[/snapback]

 

For Player/missles

8 for x,y pos

4 for player pointers

4 for player/missle height

48 for playfield

1 for playfield scrolling

----

65

 

Ball:

3 additional bytes

969583[/snapback]

So, basically, you could get one line of text in RAM. Or maybe two, since the RAM used for the character pointers can be reused outside the kernel.

Link to comment
Share on other sites

I hope that there is still enough for a couple of 12-char strings after this!

Well, if you rewrote the code to have pointers to each line, you could eliminate one of the other variables. Let's see...

13 pointers, each to a line of text = 26 bytes

969387[/snapback]

 

Why do you need thirteen separate line pointers?

 

I would suggest that you would probably be better off with an array (users can use as many or as few items as they want) of two-byte items. Each item contains thirteen bits of address plus a three-bit line counter. An MSB value of zero would end the list.

 

I would suggest storing text as the address LSB for a 43-character set (6 pixels high), shifted right one pixel; control codes would have the MSB set. Control codes would include insert-character, insert-number (two BCD digits), insert-string (not nestable), change-color, and change line spacing.

 

A game like Dark Mage could use a three-item display list: status bar, main screen (up to eight lines), and bottom bar. Thus, instead of using 26 bytes for static display pointers, it would only need six (though some other variables would be needed within the kernel:

 

Pointer within display item (2 bytes)

Pointer within display list (1 byte)

'Stacked' pointer/expansion temp (used for insert-BCD or insert-string)

Current text height

Next scan line number to do something interesting

Pointers for current line of text (12 or 24 bytes, depending upon whether venetian blinds are used to reduce flicker)

 

To minimize bouncy-text issues when the kernel has trouble getting everything done in time, I would suggest setting TIM64T once at the start of the screen and then, immediately before displaying each line of text (once it's been all calculated) wait for INTIM to reach the proper value (looked up from a table). This would help maintain nice sync in cases where the overloading line wasn't at the bottom of the screen.

Link to comment
Share on other sites

Well, if you rewrote the code to have pointers to each line, you could eliminate one of the other variables.  Let's see...

13 pointers, each to a line of text = 26 bytes

969387[/snapback]

 

Why do you need thirteen separate line pointers?

For ease of use, both in programming and compilation. With 13 pointers, each line can point anywhere in ROM or RAM. Therefore, print "HELLO, WORLD!" would compile as:

 

text:

.byte "HELLO, WORLD!"

 

and the pointer for the current line would be set to "text." With RAM, a print a$ would simply set the pointer to RAM. This is easy and effective.

 

I would suggest that you would probably be better off with an array (users can use as many or as few items as they want) of two-byte items.  Each item contains thirteen bits of address plus a three-bit line counter.  An MSB value of zero would end the list.

 

I would suggest storing text as the address LSB for a 43-character set (6 pixels high), shifted right one pixel; control codes would have the MSB set.  Control codes would include insert-character, insert-number (two BCD digits), insert-string (not nestable), change-color, and change line spacing.

I don't want to add more complexity than needed for the bB environment. Requiring users to remember all this would go against the original vision of bB. And packaging all the complexity in the compiler would also, as the asm would be hard to follow with all that bit twiddling going on.

 

I would much rather store text as ASCII. It's just so much cleaner/easier and the character set could be expanded without much pain. And I don't think that wasting a few bytes of ROM space is a big deal if the text is stored this way. Though I do like the idea of a color change option for every line of text. But to avoid needing a byte for each line, I do like the idea of using the upper 3 bits - we could get 8 colors in there.

A game like Dark Mage could use a three-item display list: status bar, main screen (up to eight lines), and bottom bar.  Thus, instead of using 26 bytes for static display pointers, it would only need six (though some other variables would be needed within the kernel:

 

  Pointer within display item (2 bytes)

  Pointer within display list (1 byte)

  'Stacked' pointer/expansion temp (used for insert-BCD or insert-string)

  Current text height

  Next scan line number to do something interesting

  Pointers for current line of text (12 or 24 bytes, depending upon whether venetian blinds are used to reduce flicker)

 

To minimize bouncy-text issues when the kernel has trouble getting everything done in time, I would suggest setting TIM64T once at the start of the screen and then, immediately before displaying each line of text (once it's been all calculated) wait for INTIM to reach the proper value (looked up from a table).  This would help maintain nice sync in cases where the overloading line wasn't at the bottom of the screen.

969666[/snapback]

More features in less space, yes, but so, so much harder to program. I think the feature set might be better suited for a kernel that one may use with assembly language, not bB.

 

My goal is not to make games exactly like Dark Mage, but as a text screen that has similar features and feel to a real 8-bit computer. I'd have commands like print, line (select current line), cls, and print could display static text or a string variable or two, and scrolling would be automatic.

 

Also, I think that the original space estimate was off - the 15 bytes for the score weren't counted.

Therefore you can get two string variables.

Link to comment
Share on other sites

For ease of use, both in programming and compilation.  With 13 pointers, each line can point anywhere in ROM or RAM.  Therefore, print "HELLO, WORLD!" would compile as:

 

text:

  .byte "HELLO, WORLD!"

 

and the pointer for the current line would be set to "text."  With RAM, a print a$ would simply set the pointer to RAM.  This is easy and effective.

 

Suppose a user wants to create something like the Stellar Track status screen (simplify as much as you think necessary). How would you go about it?

STARDATE. 26
ALIENS. . 20
ENERGY. 3000
PHOTONS. . 9
LAUNCHER. OK
PHASORS . OK
ENGINES . OK
SR SCAN . OK
LR SCAN . OK
QUADRANT 2,1
SECTOR 4,2

Using the embedded control codes, it would not be overly difficult. The trickiest bit would be figuring out how to either tell BB to store certain variables in BCD, or else minimizing the table space required for fast binary->character conversion. Otherwise, I would expect something like:

Statusscreen:
 .msg "STARDATE ",Stardate:2
 .msg "ALIENS   ",Aliens:2
 .msg "ENERGY  ",EnergyH:2,EnergyL:2
 .msg "PHOTONS    ",Photons:1
 .msg "LAUNCHER   ",Launcher:2
...
 .msg "QUADRANT ",QuadX:1,",",QuadY:1
 .msg "QUADRANT ",SectX:1,",",SectY:1

 

I am assuming some method of 'jinxing' the two-digit display to allow special text to be displayed for a few values >100. With such facilities in place, nice multi-line status displays as seen in Stellar Track would not be a problem. Otherwise, I really don't see any way to set up VB that wouldn't be confusing (having to designate selected lines for variable display, etc.)

 

I would much rather store text as ASCII.  It's just so much cleaner/easier and the character set could be expanded without much pain.  And I don't think that wasting a few bytes of ROM space is a big deal if the text is stored this way.

 

The issue is one of processing time more than space. Not that there aren't ways around that, but in a kernel time is precious. BTW, DASM supports a directive to perform ASCII->whatever translations at assembly time.

 

Though I do like the idea of a color change option for every line of text.  But to avoid needing a byte for each line, I do like the idea of using the upper 3 bits - we could get 8 colors in there.

Sure, and you can have an option to let the user select what the eight colors are.

 

More features in less space, yes, but so, so much harder to program.  I think the feature set might be better suited for a kernel that one may use with assembly language, not bB.

 

Suppose I want to output a line: "PHOTONS: 34" where 34 is a variable. How would you expect to do it?

 

If the address of the photon count is stored along with some control codes within the message string, then there's no need to worry about the RAM/ROM distinction because all the messages would be in ROM. If for some reason it was necessary to have a message in RAM, it would be possible to do so directly, but unless all 12 bytes were needed it might be better to use control codes to insert the RAM message into the ROM string.

 

My goal is not to make games exactly like Dark Mage, but as a text screen that has similar features and feel to a real 8-bit computer.  I'd have commands like print, line (select current line), cls, and print could display static text or a string variable or two, and scrolling would be automatic. 

969723[/snapback]

 

I guess my perspective is that it can sometimes be less confusing to have something that behaves differently from something else than to have something that behaves "almost" like something else.

 

If I do PRINT "A=";A and then PRINT "B=";B is there any reason to think I shouldn't be able to "PRINT C=";C and have it work as expected? Even if you decide to keep the 13 line pointers (I'd consider RAM too precious, but you may not) going with control characters to insert variables seems much better than buffering 12-character lines.

Link to comment
Share on other sites

Suppose a user wants to create something like the Stellar Track status screen (simplify as much as you think necessary).  How would you go about it?

STARDATE. 26
ALIENS. . 20
ENERGY. 3000
PHOTONS. . 9
LAUNCHER. OK
PHASORS . OK
ENGINES . OK
SR SCAN . OK
LR SCAN . OK
QUADRANT 2,1
SECTOR 4,2

Well, you can't do more than two custom lines on the screen at the same time the way I was thinking, but this should be obvious to the user.

 

BTW - the very first program I plan to create with this is RFK 2600. Should be pretty easy to code, but the strings will take up 12k...

Using the embedded control codes, it would not be overly difficult.  The trickiest bit would be figuring out how to either tell BB to store certain variables in BCD, or else minimizing the table space required for fast binary->character conversion.

I don't want to use BCD. Any variables could be displayed in decimal, 0-255. What I am hoping is that there is some existing code base that I can reference to do this easily (I'm thinking of looking at Apple II "Integer Basic" code which uses 2-bit integers for every variable, but displays them on the screen from -32768 to 32767. I hope that Woz did some fancy footwork to get this working...)

The issue is one of processing time more than space.  Not that there aren't ways around that, but in a kernel time is precious.  BTW, DASM supports a directive to perform ASCII->whatever translations at assembly time.

The only processing I plan to do is to subtract 32. I am hoping that the blank scanlines between lines of text will allow enough leeway for this.

 

Suppose I want to output a line: "PHOTONS: 34" where 34 is a variable.  How would you expect to do it?

 

...

 

I guess my perspective is that it can sometimes be less confusing to have something that behaves differently from something else than to have something that behaves "almost" like something else.

 

If I do PRINT "A=";A and then PRINT "B=";B is there any reason to think I shouldn't be able to "PRINT C=";C and have it work as expected?

969769[/snapback]

You won't be allowed to do PRINT "A=";A. You can print static text or a string only. However, you WILL be able to do something like A$="A=";A: PRINT A$. It's not too hard to understand, and this way it will soon be clear to the user what the limitations are - since if one tries A$="HELLO":PRINT A$:A$="WORLD":PRINT A$, the result will be WORLD twice.

 

You will also be able to modify an existing line of text, by A$=textline(4) or something of that sort, modifying A$ then LINE 4: PRINT A$

 

A couple of advantages to using the 13 pointers would be:

- easy to scroll individual lines of text left or right by just inc/dec-ing the pointer.

- Easy to implement a mechanism for inputting text. It would be like entering initials on a video game, and whatever gets entered is just written directly to the variable.

 

Regardless, I won't be able to work on this for a few weeks anyway, so I will give the display list idea some more consideration.

Link to comment
Share on other sites

I don't want to use BCD.  Any variables could be displayed in decimal, 0-255.  What I am hoping is that there is some existing code base that I can reference to do this easily (I'm thinking of looking at Apple II "Integer Basic" code which uses 2-bit integers for every variable, but displays them on the screen from -32768 to 32767.  I hope that Woz did some fancy footwork to get this working...)

 

I really think you should use format-strings in the kernel. It will provide a lot more versatility and shouldn't be too difficult. If you wanted, you could use a table for very quick binary->BCD conversion at run-time.

 

The only processing I plan to do is to subtract 32.  I am hoping that the blank scanlines between lines of text will allow enough leeway for this.

 

You also have to convert the ASCII codes into character pointers. Depending upon the height of the characters and number of them, this will require shifting and/or table lookups. By contrast, if you limit yourself to about 36 7-line characters, 42 6-line characters, or 51 5-line characters, you don't have to do anything. If you store character shape data and code in two banks, you can double the number of characters you can get by switching banks halfway through a line.

 

You won't be allowed to do PRINT "A=";A.  You can print static text or a string only.  However, you WILL be able to do something like A$="A=";A: PRINT A$.  It's not too hard to understand, and this way it will soon be clear to the user what the limitations are - since if one tries A$="HELLO":PRINT A$:A$="WORLD":PRINT A$, the result will be WORLD twice.

 

From a user's perspective, how is it better to have to compose a buffer before displaying it? Why not allow ( PRINT 5,"PHOTONS: ",photons:02 ) and have the statement store a pointer to the text string (encoded) "PHOTONS: ",DEC02,<photons ?

 

A couple of advantages to using the 13 pointers would be:

- easy to scroll individual lines of text left or right by just inc/dec-ing the pointer.

- Easy to implement a mechanism for inputting text.  It would be like entering initials on a video game, and whatever gets entered is just written directly to the variable.

 

Using control codes for variable-inserts would provide this functionality as well, but do it better. If someone wants to use 12 or 24 bytes for line buffers, they still could, but that's a pretty hefty price for pretty minimal functionality.

Link to comment
Share on other sites

I don't want to use BCD.  Any variables could be displayed in decimal, 0-255.  What I am hoping is that there is some existing code base that I can reference to do this easily (I'm thinking of looking at Apple II "Integer Basic" code which uses 2-bit integers for every variable, but displays them on the screen from -32768 to 32767.  I hope that Woz did some fancy footwork to get this working...)

 

I really think you should use format-strings in the kernel. It will provide a lot more versatility and shouldn't be too difficult. If you wanted, you could use a table for very quick binary->BCD conversion at run-time.

I looked at Woz's code - it uses a lot of cycles to convert decimal->ASCII. I'm sure there's a better way. I really don't want to require all displayed numbers be in BCD.

The only processing I plan to do is to subtract 32.  I am hoping that the blank scanlines between lines of text will allow enough leeway for this.

 

You also have to convert the ASCII codes into character pointers. Depending upon the height of the characters and number of them, this will require shifting and/or table lookups. By contrast, if you limit yourself to about 36 7-line characters, 42 6-line characters, or 51 5-line characters, you don't have to do anything. If you store character shape data and code in two banks, you can double the number of characters you can get by switching banks halfway through a line.

True. But I plan to keep the chars 8 high, and this gives exactly 32 per page. I've also decided that we can get 32-127 with 3 pages this way, so we'll have lower case too.

 

Also, I don't need to subtract 32 after all.

 

To convert an ASCII to a char, we could do this:

; A=ASCII code
 ldx #0
 stx temp1
 asl 
 asl temp1
 asl 
 asl temp1
 asl 
 asl temp1
 sta pointerlow
 lda temp1
 adc #>chartable-1
 sta pointerhigh

Seems to take half a scanline - so at minimum, we'd need about 6 scanlines for conversion.

 

Right now, with 13 lines, we can afford 7 scanlines between text lines. If we just had 12 lines of text, we could afford around 9, which might allow this. Or maybe the above could go faster with a table. But regardless, I don't think that the above is much worse than the way it's done right now.

 

But if I used this many cycles between lines of text anyway, I guess I could check to see if control codes (which would be ASCII > 127) could be done in place of some of the shifting. Like PRINT "PHOTONS: ",A could be compiled as:

 

.byte "PHOTONS: ",A

 

Then this could be handled by simply checking the high bit of the ASCII char, then get the value by TAX...LDA 0,X. Then convert it to 3 pointers representing numbers 0-255. There would be around 100 cycles allowed to do this... not sure if it's possible. Woz's code probably won't work. If it gets 190, for instance, it will take a lot of cycles. It went something like this: (this is incomplete - just converts binary to 3 values 0-9)

 ldx #0
 sta temp2
 sta temp3
again:
 sec
more:
 sta temp1
 sbc multiple,x
 bcc next
 inc temp2,x
 bcs more
next:
 inx
 cpx #2
 beq done
 lda temp1
 jmp again
multiple:
 .byte 100,10
done:
 lda temp1
 sta temp4

 

 

You won't be allowed to do PRINT "A=";A.  You can print static text or a string only.  However, you WILL be able to do something like A$="A=";A: PRINT A$.  It's not too hard to understand, and this way it will soon be clear to the user what the limitations are - since if one tries A$="HELLO":PRINT A$:A$="WORLD":PRINT A$, the result will be WORLD twice.

 

From a user's perspective, how is it better to have to compose a buffer before displaying it? Why not allow ( PRINT 5,"PHOTONS: ",photons:02 ) and have the statement store a pointer to the text string (encoded) "PHOTONS: ",DEC02,<photons ?

Well, instead of having an internal buffer that would be confusing to use since it would be overwritten all the time, you would have direct control over the buffer.

 

But the control code idea is starting to grow on me... however, I still need a good way to convert a byte to 3 pointers in 100 cycles.

Edited by batari
Link to comment
Share on other sites

I looked at Woz's code - it uses a lot of cycles to convert decimal->ASCII.  I'm sure there's a better way.  I really don't want to require all displayed numbers be in BCD.

 

Woz's code is a time/space tradeoff. I'd suggest casting off hundreds (simple straightline code) and then using a couple of tables for the other digits. A little bit of a space hog but not too bad, and if you used two tables of 128 bytes each, users could define 28 "special" values that should produce two-character outputs (e.g. the "OK" status report in Stellar Track).

 

If you don't want to use quite so much space, you can shrink things somewhat (here I'm assuming 8 bytes/char font)

; Convert ACC (0-99) to two digits
 lsr
 tax ; 0-49
 lda BCD,x ; Values here are shifted right one
 rol
 and #$0F
 asl
 asl
 asl
 adc #zero_char_offset
 sta dig0
 lda BCD,x; Values here shifted, as before
 and #$78
 adc #zero_char_offset
 sta dig1

Here the table only takes 50 bytes rather than 256, but there's no longer a nice way to handle 'special messages'.

 

To convert an ASCII to a char, we could do this:

; A=ASCII code
 ldx #0
 stx temp1
 asl 
 asl temp1
 asl 
 asl temp1
 asl 
 asl temp1
 sta pointerlow
 lda temp1
 adc #>chartable-1
 sta pointerhigh

Seems to take half a scanline - so at minimum, we'd need about 6 scanlines for conversion.

Sure seems a lot harder than:

 lda (charptr),y
 asl
 bcs specialchar
 sta ptr0,x

 

But if I used this many cycles between lines of text anyway, I guess I could check to see if control codes (which would be ASCII > 127) could be done in place of some of the shifting.  Like PRINT "PHOTONS: ",A could be compiled as:

 

  .byte "PHOTONS: ",A

I'd suggest using format specifier with the variable to allow a few types of 'insertions': one-digit, two-digit (with leading '0'), two-digit (blank zero), three-digit (leading-zeroes) and three-digits (zeroes not blanked), two-digit hex, and character.

 

There would be around 100 cycles allowed to do this... not sure if it's possible.

 

Use a table lookup for bin->BCD and 100 cycles is easy.

 

Well, instead of having an internal buffer that would be confusing to use since it would be overwritten all the time, you would have direct control over the buffer.

 

Yeah, but 24 bytes is pretty expensive and it still doesn't offer all that much control.

 

But the control code idea is starting to grow on me... however, I still need a good way to convert a byte to 3 pointers in 100 cycles.

970312[/snapback]

 

It's not hard if you use lookup tables.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...