Jump to content
IGNORED

Js99'er


Asmusr

Recommended Posts

Hmm, I don't know. It works fine in Firefox on Windows, but there is a warning in the console about the sound library being deprecated.

 

Since we have at least two different Linuxes where it fails, it could be that you use a special library that is not available for all platforms. Maybe you could design a minimal test Javascript that is supposed to show an empty screen, and we'll see.

  • Like 1
Link to comment
Share on other sites

I needed a project for learning advanced JavaScript for my work, so here is my proof of concept for a TI-99/4A emulator written in pure JavaScript:

 

https://googledrive.com/host/0B68J8LwEkfDyTUdTQWlVN0VPaEU/index.html

 

You can run it from the web link or download and expand the zip to your local machine and open the index.html file. All that's required is an up-to-date browser (Google, Firefox, IE 10+).

 

Currently only the CPU, VDP, PSG, RAM and a bit of the keyboard is emulated. There 's no system ROM, GROM, DSRs, disks, i.e. none of the console's 'operating system' (the opening screen is just a VDP dump). So the programs are limited to machine code that doesn't require any console routines. Luckily I had a few of those available ;-)

 

If you want to attempt to load other programs than the bundled examples, take at the software folder and software.js to see how it works, but beware that it will probably not work. The programs are currently provided as JavaScript arrays. I have attached a small Java program (bin2js.jar) to turn binary files into JavaScript arrays.

 

I have put this together in few weeks. This would not be possible without taking advantage other peoples' work. I'm in eternal debt to Tursi, from whom I have borrowed much of the CPU emulation (plus a little from MESS), the sound emulation is using components from TSS Chiptune Sound Library and JavaGear, and the VDP emulation was based on MSX.js but has been substantively rewritten.

 

If anyone is interested in contributing to js99'er I'm thinking about turning it into a GitHub open source project.

 

[EDIT] Joystick 1 is mapped to arrow keys + Tab like in Classic99.

 

Enjoy!

 

Xubuntu 14.04 wont run locally but the weblink works fine in chromium

Link to comment
Share on other sites

After countless hours of manual bug hunting though assembly and GPL code (of which I knew nothing) I finally have the power on routine up and running. In addition Parsec and Donkey Kong are working. TI Basic is loading but crashes if you make a simple for-print-next loop. There are probably some more hours of bug hunting left....


I have fixed a problem with the sound in Firefox, so perhaps it will run now for those of you where it failed. Otherwise try Chrome, which I use for development. In IE there is no sound and I don't recommend using it (at all :)).


I need some help with the Alpha lock key, I don't really understand what Thierry is saying: "The alpha-lock key is activated by the TMS9901 output P5 (R12 address >002A) and reads together with keyboard row 4." What do I have to do to implement it? In cru.js I'm returning the key state on address 0x15 but that doesn't seem to work.


... and thanks again to Tursi, without Classic99 and the source code I would never have come this far.

js99er-1.1.zip

  • Like 6
Link to comment
Share on other sites

Hi Rasmus

 

Great work!

I just scored 44,000 on Parsec before being killed by a Dramite.

 

Just to mention, it's not just for-next loops that are not working, I tried this:

 

10 CALL CLEAR

20 PRINT "Hello"

30 GOTO 20

 

it printed "hello" five times and then locked up.

 

There's some significance there because it manages to print 5 hello's and then locks up.

Link to comment
Share on other sites

I need some help with the Alpha lock key, I don't really understand what Thierry is saying: "The alpha-lock key is activated by the TMS9901 output P5 (R12 address >002A) and reads together with keyboard row 4." What do I have to do to implement it? In cru.js I'm returning the key state on address 0x15 but that doesn't seem to work.

Confusing, isn't it. I could not get working code from Thierry's description. I suspect it is incorrect. I think I got the solution from our Lee.

 

Here is a snippet from a stand-alone assembly language key-scan (not TI ROM/GROM dependant in any way) that I wrote back in January:

 

(assuming you have scanned the keyboard, and detected a letter key (A-Z), and you have checked the shift keys and they are not engaged, you then need to check the Alpha Lock key to see if you should return an upper or a lower case key, so...

(ascii code in R0)
clr r12      ; cru address
sbz >15      ; turn on alpha lock output
tb7          ; check alpha lock input
sbo >15      ; turn off alpha lock output
jeq no_alpha ; jump if no alpha lock
ai r0,-32    ; alpha lock is engaged, convert to upper case
Note that SBO has no effect on the CPU status register, so it's safe to perform a jump after the SBO.

 

Hope this is useful.

Edited by Willsy
Link to comment
Share on other sites

It worked on my iPod touch until yesterday (very slowly and the lack of a virtual keyboard make it not very useful ;)), but now there is only a black screen, the start and stop buttons don't do anything and the software combobox displays an empty list.

Link to comment
Share on other sites

You can now try js99'er with your own MESS RPK files.

 

https://googledrive.com/host/0B68J8LwEkfDyTUdTQWlVN0VPaEU/index.html

 

If you run locally in Chrome you need to add the switch "--allow-file-access-from-files" before it will allow you to 'upload' files.

 

It's running most cartridges I have tried. It still won't run any kind of basic (Ti Basic, XB, RXB) so I guess there must be some GPL problem, but I don't know how to track it down. Apart from that the only problems I have noticed have to do with the VDP emulation, e.g. no support for magnified sprites.

js99er-1.2.1.zip

Link to comment
Share on other sites

Ah. Interesting. I think it's probably testing the GPL math functions. The following is a total guess: It's executing some GPL math functions, and comparing the result to a know, stored Radix100 string byte-for-byte. Of course, if a single bit in the 10-byte result is different then the test will fail.

 

How are you implementing this on the JavaScript side? Are you trapping GPL function calls and then doing the actual work in JavaScript (in floating point)? and then converting back to Radix100? If so, you might have an issue with loss of accuracy.

 

If however everything is implemented at the TMS9900 level, then this should not be an issue at all - the GPL interpreter is 9900 code, so you shouldn't have to do anything to get GPL to run, apart from implementing the byte-wide GROM interfaces.

Link to comment
Share on other sites

How are you implementing this on the JavaScript side? Are you trapping GPL function calls and then doing the actual work in JavaScript (in floating point)? and then converting back to Radix100? If so, you might have an issue with loss of accuracy.

 

If however everything is implemented at the TMS9900 level, then this should not be an issue at all - the GPL interpreter is 9900 code, so you shouldn't have to do anything to get GPL to run, apart from implementing the byte-wide GROM interfaces.

 

It's emulated at the TMS9900 level. I suspect there might still be a bug in one of the instructions. In JavaScript you have no 16 bit word type to work with - all numbers in JavaScript are 64-bit floating point - so you need to convert them back to 16-bit using '& 0xFFFF' after arithmetic operations. Probably something is wrong with one of those conversions.

 

I tried to log every time an instruction is used for the first time to see if this could identify the culprit, and a few instructions are used for the first time when you run a simple basic loop, e.g. JLE and XOR, but I can't find anything wrong with those.

Link to comment
Share on other sites

Okay, maybe have a look at the instructions just before those JLE and XOR instructions (especially the JLE) and make sure that the prior instructions are setting the CPU flags properly. It's probably something like that. If that doesn't work, then it will be necessary to write test-harnesses for certain instructions and run them on classic-99 and compare the results. For example, MOV and all its variants.

 

Clearly, it's very close, otherwise nothing would run at all, so what ever it is is very subtle. For me, when I was writing TurboForth, probably 99% of the de-bugging effort was spend on finding the last few errors. (Though I suspect there's still a few in there somewhere that I haven't even found yet!)

Edited by Willsy
Link to comment
Share on other sites

The bug/problem that has been highlighted by the diagnostics module is almost certainly the reason why TI BASIC and XB are not working.

 

Unfortunately you were wrong. ;-) I fixed problems with the AB and INV instructions and now the diagnostics work.

 

post-35226-0-20984700-1399032820_thumb.png

 

But still no BASIC...

  • Like 1
Link to comment
Share on other sites

 

It's emulated at the TMS9900 level. I suspect there might still be a bug in one of the instructions. In JavaScript you have no 16 bit word type to work with - all numbers in JavaScript are 64-bit floating point - so you need to convert them back to 16-bit using '& 0xFFFF' after arithmetic operations. Probably something is wrong with one of those conversions.

 

I tried to log every time an instruction is used for the first time to see if this could identify the culprit, and a few instructions are used for the first time when you run a simple basic loop, e.g. JLE and XOR, but I can't find anything wrong with those.

 

:? Perhaps I'm misunderstanding what you are doing, but radix 100 floating point numbers on the TI-99/4A are coded as radix 100 in 8 bytes (64 bits) and are not bit compatible with the 64-bit floating point representation of IEEE 754 floating point, which is coded as binary or radix 2 in those same 64 bits. The decimal (radix 10) precision is different because the TI wastes a little space for the radix 100 representation: 13 – 14 decimal digits for the TI as opposed to 15 – 17 decimal digits for IEEE 754. The exponents are also different widths: TI, 8 bits (all in the first byte); IEEE 754, 11 bits (after a sign bit).

 

The real kicker, however, is how negative floating point numbers and 0 are represented on the TI. Negative numbers have the first word (16 bits) negated (two's complement). The TI manages negative numbers in calculations by complementing the first word and tracking the sign before the actual calculation and complementing the first word of the result if it is negative. For 0, the TI only cares about the first word, i.e., 0000000000000000h and 0000FFFFFFFFFFFFh are both exactly 0. :-o

 

...lee

Link to comment
Share on other sites

Thanks but I'm emulating at the CPU level and not at the GPL level so I don't have to concern myself about the floating point representation on the TI. :)

 

The issue is that when you're doing 16-bit integer arithmetic in JavaScript you have to take to mask off the right bits. For instance, >FFFF + 1 = 0 on the TI but 0xFFFF + 1 = 0x10000 in JavaScript, so you have to use (0xFFFF + 1) & 0xFFFF = 0. Now because I converted a large part of the CPU emulation from Tursi's Classic99 code written in C++, which does have 16 bit integers, I have to add the masking everywhere, and this has been the cause of many bugs so far.

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...