This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Messages - christop
61
« on: March 04, 2011, 05:38:04 pm »
I just use the classic linear congruential PRNG in one of my programs:
unsigned prngseed;
int rand() { prngseed = 1103515245UL*prngseed + 12345UL; return (unsigned)prngseed % ((unsigned)INT_MAX+1); }
void srand(unsigned s) { prngseed = s; }
(This is a modification of my code so it works with 32-bit ints (assuming int is 32 bits on the Nspire). My program runs on a system with 16-bit ints)
These are actually implementations of the C standard functions rand() and srand(). It works pretty well considering its simplicity. It also doesn't rely on a timer to generate each successive value. You can set the seed using the timer though:
srand(*counter);
To use it with a maximum value you can do this:
/* RAND_MAX = 2147483647 with 32-bit int */ x = (unsigned long long)rand() * max / RAND_MAX;
Yeah, it uses 64-bit arithmetic (if long long is 64 bits, that is), but it is far more uniformly distributed than using "x/(65535/max)" as you are doing (except when max is an integer factor of 65535, in which case it's the same).
62
« on: March 04, 2011, 05:20:04 pm »
Punix: stands for Puny Unix. It's a small Unix-like OS for the TI-68k calcs. I was also considering a couple other names that are a little bit NSFW.
63
« on: March 04, 2011, 03:13:07 pm »
I replaced ALL rte instructions with "jbra check_rte", and in check_rte I make sure the stack pointer is correct (0x2ffa) if the saved SR has the supervisor bit clear (which means it is returning back to user space). I also test the return address against the value 0x0000002f. If either of those tests fails, it halts right there. Guess what? Nothing failed the test, but the address exception still happens. :'(
64
« on: March 04, 2011, 01:56:52 pm »
AHA! I moved the SSP to 0x3000 and it still goes to 0x0000002f. This means it's not caused by a write to the screen. BUT... I didn't notice this before but upon entry to the address exception handler, the SSP is 0x2ef2. Add 6 bytes to get 0x2ef8, which is what it was immediately before the address exception. This is 264 bytes below what it should be (0x3000). Indeed, this is the contents between 0x2ffa and 0x2fff: 2ffa: 0000 2ffc: 0041 2ffe: 6f1c That is the saved SR and PC from a trap. 00416f1c is the address following a trap #0 in userspace (with a move #3,%d0 before the trap, which means this is a read() system call--just as I suspected). What this means is that some time before the address exception (probably right before), some exception or trap handler returned without popping all its registers off the stack (264 bytes' worth). I just need to narrow down which handler is responsible and then take it out back and shoot it. After it's dead I'll replace it with a better version.
65
« on: March 04, 2011, 01:27:49 pm »
In the general case, such low addresses might be NULL dereferences... but I don't think you have any struct with a misaligned word/long field (unless you're using the packed attribute, and not using the struct type directly, otherwise the compiler should figure on its own that it needs to make multiple byte accesses)... Just to check, I'm using the packed attribute only once for struct flashblock in flash.h: struct flashblock { long blockno; char data[BLOCKSIZE]; } __attribute__((packed));
I'm pretty sure both members are word-aligned (BLOCKSIZE is an even value), and besides that, I'm not currently using the only functions that use that structure. Even in assembly code I'm pretty careful to keep addresses word-aligned, unless they point to byte/character buffers. Judging by the values of the a2 and a3 registers you posted in the bug tracker entry on SF, it could also be a (normally aligned) word/long read at offset 0x2e from the 0x1 address (which is getting misaligned for some reason). That's possible, and I'll look around for any jumps to an offset of 0x2e from %a2 or %a3. I can't think of any assembly code that I wrote that does a jmp 0x2e(%a2), so if that's what happened it must be compiled code. TIEmu does enable you to break upon address error, although after overwriting several bytes at the bottom of the execution stack. By reading those overwritten bytes, you can at least get the address of the offending instruction (minus a couple bytes, IIRC). That might enable you seeing which part of the code triggers the address error. I do have a breakpoint on the address error exception, but I want to see the contents of the supervisor stack before the exception to see if the kernel returned to address 0x2f, or if this was caused by userspace (which I doubt). Now that I think of it, the top of the kernel stack is located at 0x4c00, and it's possible that I wrote just below the screen address during a system call, and that trashed the kernel stack. I'll see if I can move the kernel stack somewhere else and then try to replicate this bug.
66
« on: March 04, 2011, 03:46:52 am »
So... one of the bugs in the betas is in the /dev/audio test. When you run "tests" and get to that test it just basically freezes the whole system, and you have to reset the calc. Turns out I was allocating a 4K stack for the user process, but the audio test tried to use 12K of stack for its own audio buffers. The stack is located near the bottom of memory, right above the kernel variables, so the process was overwriting many (if not all) of the kernel variables. Ouch! I fixed that already in my working copy, but I'm still scratching my head over another really tough bug. See this tracker page for as many details about the bug as I can think of: https://sourceforge.net/tracker/?func=detail&aid=3199268&group_id=184747&atid=910492In all the years of working on Punix I've never had this happen before, and I just cannot figure out what is causing it. It's difficult to solve because I can't make TiEmu break on the offending address (0x0000002f) before the address exception triggers. If I could I would at least be able to see what is on the supervisor stack before it is overwritten by the address exception handler. Since it happens only after many hundreds or thousands of times calling the same system call over and over (it happens seemingly at random), I can't really step through the code in the debugger and find what is causing it. I'd like to fix this bug for good and not just sweep it under the rug, since it'll pop back up when I least expect it. If any of you can crack this bug, I would be most grateful! Good luck!
67
« on: March 03, 2011, 04:19:31 pm »
Nice to see a new update When you release the final version, could you make a .9xu of it and sign it using the 92+'s OS key, instead of using TIB? To be honest, I haven't been following all of the developments in the TI calculator world very closely. Is there actually a key to sign the OS now? Yes, if I can sign it with a key to make a .9xu file instead of a .tib file, I would, at least for "production" versions (I hope there isn't a "final" version, since that implies to me that the project is unmaintained or dead).
Yeah the keys were all factored 1.5 years ago: http://www.ticalc.org/archives/news/articles/14/145/145273.html
TI responded with a DMCA notice, but the TI community won with the help of the EFF.
Yup, I remember the DMCA notice, but I forgot that it was about the OS keys. Go EFF! I'll have to add signing the OS to my Makefile sometime between now and an actual release.
68
« on: March 03, 2011, 04:07:46 pm »
Btw I wonder if Christop algorithm is the same as the one used in the RealSound video player that got featured on ticalc.org a few years ago?
Are you referring to this one? http://www.ticalc.org/archives/files/fileinfo/385/38513.htmlAs far as I know, that only plays sound. That is the only RealSound player I could find on ticalc. Regarding Floyd-Steinberg dithering, yes, it looks better (I tried it already), but it decreases the amount of compression possible because it changes more pixels between frames than ordered (Bayer) dithering. A better encoder might do a better job at handling it, though. (A better encoder might pass through the video twice: once to generate the best tile set for that video, and then again to do the actual encoding)
69
« on: March 03, 2011, 03:47:35 pm »
I just uploaded Beta 2. This release adds support for command arguments in the shell, including support for quoting (both double and single quotes) and character escaping (using the backslash \ character), almost exactly like a real shell. I also added the "echo" command, and "cat" can now open files and write them to standard output. Punix only understands only a few built-in filenames at the moment: /dev/{vt,link,audio,random}. You can try cat'ing any of those files but you might not like the results! You might have to reset the calculator afterwards too. Download beta 2
70
« on: March 03, 2011, 01:29:28 pm »
(But for some reason cat doesn't work)
I hate to put it this way, but it Works For Me(tm). The shell doesn't pass any arguments to the applets, so without arguments, cat only echoes (echos?) each line that you type. Type Control-D to exit cat. This is how cat works on a "real" *nix too. Note: I don't think I mentioned this anywhere yet (besides inside the source code), but the diamond key is Control, 2nd key is Alt, and MODE is Compose (similar to the Compose or "Multi" key in X11). Type MODE plus two characters to type a single "special" character. For example, MODE c / types a cent symbol, and MODE i " types i with an umlaut. The full list of combinations is in keyscan.c. When you release the final version, could you make a .9xu of it and sign it using the 92+'s OS key, instead of using TIB? To be honest, I haven't been following all of the developments in the TI calculator world very closely. Is there actually a key to sign the OS now? Yes, if I can sign it with a key to make a .9xu file instead of a .tib file, I would, at least for "production" versions (I hope there isn't a "final" version, since that implies to me that the project is unmaintained or dead).
71
« on: March 03, 2011, 03:38:02 am »
I'm pleased to announce the first Beta release of Punix! Download the compiled TIB file here from SourceForge. This is a ROM for the TI-92+. Open that file in TiEmu (or another TI-92+ emulator) and boot it up. DO NOT SEND IT TO A REAL CALCULATOR! DON'T BLAME ME FOR BRICKING YOUR CALCULATOR IF YOU DO ANYWAY! You can read the full release notes (including some tips and things to do with it) here. Let me know if you have any questions or find any bugs (besides regarding the overall incompleteness of the system). I already know a few bugs cropped up somehow during this release that weren't there before... Strange how that happens.
72
« on: March 02, 2011, 09:07:22 pm »
Will betas and the final version be available in binary form too? It might be a bit too much to recompile it everytime a new build comes out, but a lot of less tech-savy calculator/computer users tend to have troubles compiling softwares, as we could see with Ndless 2.0 with the flood of questions asking for help on how to compile Ndless due to errors.
Yes, I will definitely release compiled binaries for betas and release versions. Up to this point I haven't felt that it was ready to call it a beta (I still consider it to be alpha), but now I do have a semi-usable shell and a somewhat functional kernel, so maybe I ought to release a beta to let people try it out easily in an emulator. Let me commit my recent changes (mostly to the userspace shell) and then I will release a binary soon.
73
« on: March 01, 2011, 02:46:16 pm »
Awesome job! This topic reminded me of a video player I was writing back in 2009 but never finished. My video codec only supports monochrome videos (only dithering, no grayscale), though, so it's not really the same as yours. With the way it works, it would probably be difficult to adapt to grayscale too. I wrote an encoder and decoder that run on my computer, but I designed the compression format to make it fast and easy to decode on a 6MHz Z80 (I was targeting my trusty ol' TI-86). The GIF animation I attached shows the output of the decoder (after scaling and stretching it to the same aspect ratio as the TI-86 screen and converting to GIF). The video is 4:36 long and runs at about 8 fps. The compressed video is 577 KB long, so it's about 260 bytes per frame, or 2KB/s. The source is Red Hot Chili Pepper's "Can't Stop" music video. I think I used FFMPEG to dump the video to individual images (I can't remember what format it dumps to, probably JPEG), eventually converted them to Portable Pixmap (PPM) format, scaled and cropped them, dithered them, and then concatenated them into one file, for my encoder to read. These steps are all fairly easy to do in batch with the NetPBM utilities. Here's how the decoder works: the input file contains a list of 8x8 pixel tiles. The decoder saves these for later. Each frame consists of 16x8 tiles (128x64 screen / 8x8) running from top to bottom, left to right (column-major order). For each tile, the decoder reads a byte. If the byte is less than 128, then it is an index into the list of tiles. If the byte is 255, then the decoder reads in 8 more bytes and uses those as a "literal" tile. Whichever tile it uses (either from the list or a "literal" tile), the decoder XOR's the tile onto the previous frame at the current tile location. I chose to use XOR so the video can be played backwards (eg, rewinding) easily. To play a video backwards, the decoder XOR's the tiles exactly the same way. Besides 0-127 and 255, there are several other byte values that are special too. The values between 128 and 143 mean "rotate the tile in the frame". By rotate I mean rotate each byte left or right, and rotate the bytes up or down. This is kind of like shifting the tile horizontally and vertically, but since I'm rotating the tiles, it's reversible (again, so the video can be played backwards). Bits 0 and 1 indicate how many pixels to rotate horizontally (-2, -1, 1, or 2), and bits 2 and 3 are for the vertical shift amount (same as the horizontal). Like the tile XOR operations, tile rotations operate on the tile in the previous frame. To play a video backward, the decoder has to rotate each tile in the opposite direction. This leaves byte values 144 through 254 for other reversible operations. These are currently unused in my decoder but might be used in the future. Here's the overall byte format: video header: 1 byte=n (number of tiles) 8*n bytes=tile data frame: 1 byte=frame type (most are 2 for "cumulative", but other values are possible, eg, 0 for end of stream) 128 tiles tile: 1 byte=transformation type 8 bytes=literal tile (if type=255) I haven't done this yet, but at the end of each frame I should probably write a 2-byte value that says how large that frame was, so the decoder can skip to the beginning of each frame when playing a video backwards. One other idea I was playing with is to losslessly compress each lossy-compressed frame, but initial results show larger file sizes when this is done. It could be that the RLE compression method that I used on the frame data just isn't suitable for that type of data (I think it was basically the RLE used by the PCX format). This is an area I'll investigate further. Based on this description of the decoder, it should be obvious how the encoder works, right? It basically just has to come up with a good set of tiles to pass to the decoder, and then for each tile within each frame, decide which tile adjustment (using a tile index, literal tile, or other transformation) results in the "best-looking" tile in the output. "Best looking" is subjective, so the encoder really determines the quality/size tradeoff (up to the hard limits of the format, which is currently 129 bytes/frame minimum). Edit: tiles are actually stored in column-major order, not row-major order. That should make decoding slightly faster than row-major order.
74
« on: February 28, 2011, 07:41:01 pm »
As a curiosity, I downloaded and compiled BusyBox 1.18.3 using the TEST_config_nommu configuration, and it produced a 519296-byte stripped binary. Obviously this would be too large for the calculator, but it also includes far more utilities than are needed:
Currently defined functions: [, [[, add-shell, addgroup, adduser, ar, awk, base64, basename, bbconfig, blockdev, bootchartd, bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, cksum, clear, cmp, comm, cp, cpio, crond, crontab, cryptpw, cttyhack, cut, date, dc, dd, delgroup, deluser, devmem, df, diff, dirname, dnsd, dnsdomainname, dos2unix, dpkg, dpkg-deb, du, echo, ed, egrep, env, envdir, envuidgid, expand, expr, fakeidentd, false, fgrep, find, flashcp, flock, fold, fsck, fsck.minix, fsync, ftpd, ftpget, ftpput, fuser, getopt, getty, grep, gunzip, gzip, halt, hd, head, hexdump, hostid, hostname, httpd, hush, id, ifdown, ifup, inetd, init, inotifyd, install, iostat, ipcalc, ipcrm, kill, killall, killall5, klogd, last, length, less, linuxrc, ln, logger, login, logname, logread, lpd, lpq, lpr, ls, lspci, lsusb, lzcat, lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mesg, microcom, mkdir, mkfifo, mknod, mkpasswd, mkswap, mktemp, more, mountpoint, mpstat, msh, mt, mv, nbd-client, nc, nice, nmeter, nohup, nslookup, od, passwd, patch, pgrep, pidof, pipe_progress, pkill, pmap, popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pwd, rdate, rdev, readlink, readprofile, realpath, reboot, reformime, remove-shell, renice, reset, resize, rev, rm, rmdir, rpm, rpm2cpio, run-parts, runlevel, runsv, runsvdir, script, scriptreplay, sed, sendmail, seq, setsid, setuidgid, sh, sha1sum, sha256sum, sha512sum, sleep, smemcap, softlimit, sort, split, start-stop-daemon, strings, stty, su, sulogin, sum, sv, svlogd, sync, sysctl, syslogd, tac, tail, tar, taskset, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, true, tty, ttysize, udpsvd, uname, uncompress, unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, usleep, uudecode, uuencode, vi, vlock, volname, wall, watch, wc, wget, which, who, whoami, xargs, xz, xzcat, yes, zcat With only a shell and about a dozen of the most common utilities compiled in (eg, cat, echo, ls), it would probably be about 10k-20k, which I think is reasonable.
That's a while off, though. I need to finish the filesystem (as I mentioned already) and develop a development environment for compiling programs for Punix (TIGCC has too many TI-AMS assumptions built in, and it can't output the appropriate binaries for Punix either--besides the Punix kernel itself, of course).
75
« on: February 28, 2011, 06:26:39 pm »
I've tried to compile it once, but I failed (probably I did something stupid). The screenshot show that you have already written a shell for it, which makes me even more happy
It probably wasn't you. I stupidly left Punix un-compilable since r202, which was almost a year ago now (yikes! where does the time go?). I fixed that problem 3 days ago in r211. Note that the Makefiles only work under *nix systems, or possibly with Cygwin/MinGW under Windows, since they use *nix shell commands (eg, date and tail). If you're using Windows, that might be another reason it failed. If you're using Linux, try compiling it again, and let me know how that goes. The shell that you see is really just a mockup. It reads a command and has a big chunk of if (!strcmp(cmd, "somecommand")) statements. It doesn't search the filesystem (since there is none yet) or do anything fancy like piping or redirection. I'm using it to test various functionality of the kernel or some library routines. Once I get a filesystem working and can execute binaries from the filesystem, I'll probably just port an existing Bourne-compatible shell to it... something like ash, zsh (not the TI-8x shells with the same/similar names ), or Busybox. With Busybox, I would also get a lot of standard utilities built-in. W00t!
|