Some Programming Challenges

Started by airship, September 14, 2007, 03:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

airship

re: #1 - I've uploaded a ZIP file that contains the following files:

    The two Twin Cities 128 articles on serial spooling
    Two txt files of the program listings
    Two C128 program files derived from the listings

http://home.mchsi.com/~airship1/serial.zip

I think you'll find them very interesting. I did.

DISCLAIMER: The PDF is from page scans that I spent a LOT of time cleaning up, so it should read pretty accurately. The program listings were OCRed from the PDF. Though I've been through them several times, they may still contain errors. The program files were automagically generated by Tok64, then loaded to see if they looked ok in VICE. They should be fine, but I had to OCR them here at work and I haven't been home to actually run them yet. Though I DO have VICE up and running here, I really don't trust it to do much of a job on programs that use m-r and m-w commands. :)
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

Korodny

Hello guys, I'm new here. Nice forum!

Quote from: hydrophilicBacon, I agree the REU is very fast.  At 1M/s, it would take about 1/9 second to transfer 128K.  This would seem 'instant' executed in immediate mode, but would be evident (not so instant) when programs are multi-tasking...
I don't think you can implement multitasking on top of the existing DOS and using the existing set of applications.

With the C128's standard Kernel, there's no way of running an application "in the background" - if it runs, it grabs/requires all the ressources available. Imagine you're editing a text with ZED in 'task' 1, while task 2 (running in the background) would be a game of Reversi.

As soon as the Reversi game would have finished calculating the computer's move, it would listen to keyboard input again. The next time the task switcher activates Reversi's task, it would empty the keyboard buffer - i.e. eat up key strokes that were actually intended for the other task. Another problem would be that both tasks require access to the video RAM, so you'd have to switch displays aswell as tasks. Multitasking can't be that much fun if your display is switching from ZED to Reversi two or three times per second.

If you really want to have real multitasking, you'd better use a dedicated OS, like the C128 port of Lunix.

But the idea of using a REU for task switching sounds very nice, especially as C128 software should be pretty compatible with that kind of approach (no fancy raster interrupts or stuff like that).

airship

Hydrophilic, I did not understand a word you said. Cool. You've given me a lot to research.

I just made a bid on SIX 1541s. I'm thinking of using one with its drive intact as a master, stripping out all the other drives, and stacking the boards to make a parallel machine: one master, six slaves, and a C64 on the bus for setup, input, and display. Of course, it would use the serial bus to communicate, just as we're discussing here.

I believe that the parallel stack controller would have the opposite problem of the computer: whereas the computer has no easy way to listen for ATN, the master 1541 would have no easy way to generate ATN. Right?

I've already thought that it might be cool to implement a cryptography program. Each program would get a block of 256 characters to encrypt at a time. They'd be encrypted, then sent back to the master for storage on the disk. One thought I had was to implement the ROM routine for GCR encoding as part of the encryption scheme. :)

You could also calculate digits of PI in parallel and store 170k digits on each floppy.
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

hydrophilic

Quote from: airship...whereas the computer has no easy way to listen for ATN, the master 1541 would have no easy way to generate ATN. Right?
Right the Commodore disk drives can't output ATN.  But it would be an easy hack to allow this.  The 1541,71,81 all have unused output lines on their I/O chips (this is also how the parallel I/O hacks work).  Of course you would a need a little more power to drive the line.  I think the '41 has an unused gate that could work, but you'd probably need to add a small chip ($0.25) for the '71,81.

Quote from: airshipYou could also calculate digits of PI in parallel and store 170k digits on each floppy.
:D :D :D
If you used that for encryption, that'd be 170*1024*8 = 1,392,640-bit encryption.  Better not publish such a program or you'd be in violation of cryptography export laws!  With such an insane bit length, even the NSA/CIA/FBI/KGB/FSB (all working together) couldn't crack your message... except the digits of PI are well known.  (but do they know the GCR coding of PI ?)

Quote from: KorodnyI don't think you can implement multitasking on top of the existing DOS and using the existing set of applications.
N-Progrs does implement a very primitive co-operative multi-tasking with existing BASIC apps that don't use DOS commands.  In this limited case, programs are aware of each other so shouldn't have problems you mentioned.

However, you made very valid points to be considered for pre-emptive multi-tasking.  Such a system (unlike N-Progs) would need to:

1) manage files seperately for each task
2) maintain seperate keyboard/input buffers
3) maintain seperate screen/output displays

Obviously #1 would be the biggest challange.  #2 is trivial since the keyboard buffer is only 10 bytes.  #3 could be done in two ways: if the app uses standard KERNAL I/O for screen, you could just use seperate memory for screens (this would be fast); otherwise you'd have to copy memory to the 'standard' location on task switch (slow but more compatible).

I also agree if you want true, reliable multi-tasking it is best to go with an OS desgined for it.  But this has the severe disadvantage that you have to throw away all your existing apps.

Edit
Quote from: airshipI've uploaded a ZIP file...
Those articles were very informative!  Heck, I never knew SPOOL was an acronym :)  You might consider adding the articles to the sub-forum on this site.  I'm sure others would find the info useful (it would be easy to find that way).

airship

Tell me more about this 'unused gate' on the 1541...

In its first incarnation, I'll probably just stack 8 drives and let the C64 handle control using regular DOS commands and files. That way each unit can have its own drive to use not only for data input and output, but also as scratchpad memory. This would add a lot of flexibility to the kinds of routines you could run. (Manipulating large arrays on disk?)

If you used all 40 tracks without a BAM or sector headers, you could store, what, up to 192K of M/L for each drive, or 768 separate 256-byte M/L routines. That's a pretty big program. Of course, I'd also want to store input and output data on the same floppy, and I probably wouldn't abandon the standard DOS formatting unless I had to. Still, it's fun to contemplate.

I'm currently checking out various M/L routines to see which ones will fit in 1541 RAM. I'm especially interested in any that will do convoluted math on individual digits of long problems. Think: computing digits of PI, cryptography, fractals, etc. If you have any suggestions or sources for 6502 routines (other than 6502.org), let me know.

But here's another problem: You can only physically change the device number on a 1541 to 8, 9 , 10, or 11 by cutting pads or bending pins 15 & 16 on 6522/2. You can change it to a higher number in software, of course, but is there a relatively simple hardware hack for devices 12, 13, 14, & 15? I'm thinking it would be cool to eventually hack a retro rotary switch to each for device selection.

I've also heard it claimed that using a drive as unit 15 is unwise. Any idea why?

BTW, I also found the print spooling program in Abacus's 'Anatomy of the 1541' which was published in June of 1984, a year before there even WAS a C128!

ALSO, there are a few typos in the executables and text listings in the ZIP I uploaded. I haven't had time to fix them yet, but when I do I'll post here.
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

nikoniko

Quote from: airshipIf you have any suggestions or sources for 6502 routines (other than 6502.org), let me know.
Well, you could disassemble some demos to see how they perform their mathematical magic. :P

Before you do that, however, you might want to check out the math routines section of the C64 Codebase wiki.

I don't think there will be any problem fitting calculation routines for things like fractals even in the limited RAM of the 1541, unless you're trying to use something that relies on 4K of lookup tabes or something.

airship

Thanks. I forgot about the C64 Codebase Wiki. There ought to be some innovative demo code there!

And even with 4K of lookup tables, you could always put the tables on disk and load them 254 bytes at a time...
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

nikoniko

Quote from: airshipAnd even with 4K of lookup tables, you could always put the tables on disk and load them 254 bytes at a time...
Well, if the purpose of the lookup table was to speed up calculations, that would kind of defeat the purpose. :P

In most cases, you'd probably do better with a routine that takes more cycles but doesn't require a large lookup table. Or use smaller tables if you can still get the required accuracy. It should be possible to do fractal calculations and even simplistic raytracers entirely in 1541 RAM, flushing your pixel buffer to disk (or sending it back to the C128) whenever you finish X number of pixels. Have each drive process different rows, and you could have some zippy little multiprocessor fun going there.

airship

How about adapting KIM-I Microchess? It fits in 1K. By stripping out the screen display code, it should fit in 3 of the 4 buffers of the 1541, leaving one for DOS disk accesses. There's a version that uses an RS-232 terminal here ( http://6502.org/source/games/uchess/uchess.htm ) that could be used by replacing the RS-232 code with IEC serial communications calls.



You could set up a tournament where the 1541s would play against each other simultaneously (4 ongoing games at a time) according to matches set up by the C64. The C64 UI could selectively display any game in real-time while the others continued in the background.

Shoot, with each drive actually playing chess, I wouldn't even care if the C64 had to act as traffic cop for them. My original idea was to be able to have them communicate directly. Maybe they still could, but... I mean, they'd be PLAYING CHESS!!! How cool is that?

In future versions, each 1541 could potentially learn from its mistakes by creating lookup tables on disk that said 'In the 303 games when the board looked exactly like it does now, when I made move zz-1, xy-3, or po-4  I usually lost, but when I made move xx-7 or pq-6 I usually won; pq-6 has a little better win rate, so that's what I'll do'.If one drive got so that it won most of the time, you could DUPLICATE its disk for each of the other drives so they would all start out just as good as each other again. Or you could come up with a C64 program that would integrate the experiences of ALL the drives on a regular basis, then create a new master disk for them all to start with.

You could even play human against any one of the drives. Or all of them, round-robin style.

Is that cool enough? :)
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

nikoniko

Hmm... for I/O, could you share between your real drive system and your 64HDD setup, so that instead of reading/writing floppies you could use the networked PC? Then you could relieve some of the I/O burden and focus on the power of having many 2Mhz processors at your disposal. Sure, it's not quite as cool as the pure approach, but would still be pretty nifty.

Guest

A couple of years ago I posed a question on c.s.cbm about using 1541's as a distributed computing grid with a C64 as the controller.  I was told I was nuts and it would be useless.  Now, I'd really like to see this chess idea to fruition.

BTW, I'd say let each drive log it's own learned patterns, then you can see what happens when drives with different experiences plan against each other.  This would be a true learning super-computer as it would have far more realistic simulation of how humans learn.

airship

I'd like to keep it pure CBM. There's just something so right about having the drives use their own floppies.

And they wouldn't even be doing that until the 'upgraded' version with lookup tables. In version 1.0, the C64 would load the drive runtime routine from drive 8 and send it over the serial bus to each drive in turn. Then it would set up tournament opponents and go into monitor and display mode. Not even the C64 would read or write to a drive after that. The 1541s would run MicroChess without drive or bus access until they had a move to transmit, or needed to input a move from their opponent. I don't know how long it takes for the 6502 to make a move in MicroChess, but I imagine it's long enough that the bus won't be too busy just moving a couple of bytes per drive each time a move is made.

Even in v2.0, reading and writing lookup tables on their own floppies wouldn't take up the serial bus, though it WOULD take up a buffer. With no reading or writing going on at all, we'd have the full 2K to play around with (plus usable ROM routines).

Hmmmm... If a drive is spending 1/2 of its time waiting for its opponent to make a move, why couldn't it play TWO games of chess at once? It could just play against itself but that wouldn't be nearly as much fun, I don't think, as playing another unit. Interesting...

How about 'multitasking chess'? Each 1541 would just be a generic chess player. The C64 would be the master controller for any number of ongoing games, be it one or a thousand. You could use one 1541 for as many individual unit numbers as you could configure. The C64 would keep a table of board setups for each game. As each 1541 made its move on its current game, the C64 would log it and change the board setup for that game and push that game on the 'move pending' stack. It would then send the board setup for the top game on the stack to that 1541 and tell it to run. Rinse. Repeat. I LIKE IT! :D

BYW, 1541s are 1MHz. ;)
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

Guest

Another idea, do this with 1581's instead of 1541's as they have a lot more storage and are a lot faster.  Hell, get some CMD-HD drives involved as well!

airship

Payton, Payton, Payton... the idea is to do this with creaky old hardware in a super limited environment. That would be CHEATING! :)
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

nikoniko

Well, 1581s wouldn't be cheating... they've got the Commodore name on them, after all. :P

EDIT: The true Commodore name, that is. We can't have the new Commodore Gaming PCs trying to muscle in. :D

hydrophilic

Quote from: airshipTell me more about this 'unused gate' on the 1541...
On the original 1541s (this may be different for the 'C or 'II) there is a quad NAND gate UC7 and the first NAND gate (pins 1,2, and 3) is unused.  The schematics show the inputs are both grounded and the output disconnected.
Edit
Further examination reveals it is a NOR gate.  Unfortunately the schematic I have is a low-res scan and many things are illegible.
/Edit
Cut the input traces to ground, then route both to a VIA output line.  Route the NOR output to the ATN line.  In theory!  For this to actually work, the NOR would need to have an open-collector output.  I don't have a TTL data book handy so I don't know.  In fact from the schematics, I can't tell if its 7402 or 7403 EditI believe it is a 7402 by reference to another schematic/Edit.  Looking at the schematics, it appears NOT to be open-collector, bummer!

You would probably want the C64/128 to fascillitate the IO since incorporating direct communication would require custom IO routines which would take a bit of RAM.  At least 128 and probably 256 (or more) bytes.  Of course this is just a guess based on fast-loader experience which is quite a bit different than the current application.

airship

Well, my first step is to trim the C64 adaptation down to bare bones. I'm separating out the I/O routines so they can be relatively easily replaced with serial when I move it to the 1541s, plus I want the C64 version to co-exist with BASIC.

I could only find 56 relatively free zero page locations on the C64 (RS-232, cassette, etc.), and only one block of 16 contiguous bytes. I need two blocks of 16 bytes as the code is currently written, plus another 30 single-byte zero page locations. That's 62 bytes. So not only am I 6 bytes short, I'll have to split the backup board into two 8-byte chunks to get it shoehorned in there. I think I can put the backup board in main memory - its only used by one routine, I believe. But the main board HAS to be in zero page and it HAS to be 16 contiguous bytes. It's just used too often.

I can keep the code shorter if I just load the entire 1541 zero page with a M-W on each change of sides. I'm thinking I can read zero page from an idle drive, overlay the variables on it, and reload it back in on every move, with the new board, counters, etc., already in place. I'll probably run into some problems with that. If I do, I'll have to use multiple writes to zero page blocks to do the setup. This is cheating a bit, as it relies on the C64 to do the setup portion. My hope is that this approach will make the code short enough that I can keep a buffer open to let the drive actually act as a drive while playing chess. Otherwise, what's the point? :)

I want to keep the C64 version BASIC-compatible so it can run in the background while the BASIC interface program is running. That way you could have eight 1541s, the C64, AND a human all playing each other simultaneously.

I'm trying hard not to get started on the display/control/user interface program until I get Microchess working the way I want it to. My M/L is VERY rusty and I don't want to get drawn into the BASIC part or I'll never get the M/L done.
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

airship

Uh-oh. I haven't even finished my first pass through the original Microchess code and I find this article on an IMPROVED version! Feature creep already!

http://www.atarimagazines.com/computeii/issue1/page19.php
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

hydrophilic

Is the BASIC code going simply going to call the ML routine on the 64, or will the ML be running in the background via IRQ?

If BASIC simply SYS the code, you can use FAC, ARG, and TMPFAC.  Thats over 15 bytes but its not all continous.  Of course this is temporary ZP memory so save anything you need between SYS's someplace safe.

airship

Thanks, but I've already got all of those. I need more!!! :(

I need every zero page location that's not used by system maintenance (i.e. if you use it the system hangs), screen display, keyboard input, or IEC communications. I think I have them all, but if you have any more insights, they'd be appreciated.

For the first pass, I'm going to use pure M/L, with Kernal calls for user I/O. That will be just human vs. Microchess. Once that works, I'll rewrite it to work in the drives. Last is getting a working version in M/L that will run behind the BASIC interface for the drives. Its got to run via IRQ. I don't want the BASIC program halting while the chess routine runs.
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

nikoniko

Why not develop it on the 128? At least on the 128 you can set up your ML with its own zero page. 256 contiguous bytes of zero page goodness for you to use. Then later on you can port it to the 64. For the 64 port, I'd recommend not worrying about sticking every program variable in zero page. Since your ultimate goal is to have it running in the background, which will make it slower than your drive-based version anyway, might as well stick some of your variables in main memory. Or, my personal suggestion would be not to have a 64 version at all, but only use the 64 as the gamesmaster. Code up something to keep track of statistics, let you peek in on games in progress on the drives, let human play against one or several drives, etc, and leave chess to your 1541s.

airship

That's really all I wanted to do on the C64, have it run the system and not play chess at all. But since I'm developing the 1541 drive version there anyway, I thought, hey, why not keep a copy in the background to make one more player? You could even then use it a a stand-alone person-vs-computer program, though there's already a version of Microchess that does that. It's just a nice side effect.

Obviously I would love to do this on a C128, but a C64 is capable of doing it. Since I've got a half dozen idle C64s sitting around, I thought this way I could just stack them all up with a 1702 when it came time to test, without tying up my 128.

I've already thought that the really cool thing to do with a C128 would be to set up a bunch of 1K program spaces, each with its own zero page, and let them go at each other. Microchess makes a move about every 5 minutes on a 1MHz KIM-1. That's the same speed with 2 programs playing each other on a 2MHz C128. With 4, you'd run half-speed. With 8, 1/4 speed. Right? So you could play a complete chess tournament with 4 concurrent games, and one move (not each, but total) being made every 2.5 minutes. Heck, that's much faster than most human tournaments I've seen!

No matter HOW many microchess instances you had playing each other, you'd still get one move about every 2.5 minutes. So you could run, say, 96 instances playing 48 concurrent games, and still have room for a nice tournament master and board display program. Maybe even in BASIC. :)
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

airship

RE: the idea of calculating Pi to an arbitrary number of places in a 1541 and writing it to disk...

It seems that GMTA. There's this thread on Google Answers from 2002:

http://local.google.com/answers/threadview?id=33189

In which a guy called googlebrain-ga posted this:

QuoteSomewhere, I have a disk with a program that caused a 1541 Disk Drive to calculate Pi, and write the data to an inserted disk. I was very bored that week. If I can find it (Even if I still have the disk, it'll be seriously old) I'll post the source here. It wasn't very long, but it was all ML (Obviously, since the drive didn't support any high level languages.
Needless to say, he never came back to post the code. Arrrrgh! I'd love to see what he did. Has anyone, anywhere ever heard of this? Did it make it into the wild? Or do you just think he's bragging?

Golan - do you know this guy? :)
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

Golan Klinger

Quote from: airshipGolan - do you know this guy? :)
You probably won't believe me but that program was written by Ken Kopin. I dropped him a line to see if he still has the code kicking around. I'll let you know.

I told you: Everybody. I've square danced twice in towns you've never even heard of. :P
Call me Golan; my parents did.

Blacklord

Quote from: gklingerI told you: Everybody. I've square danced twice in towns you've never even heard of. :P
The Queen said she wants her slippers back.......

Lance