Skip to content

TFHFony/WebMSX

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WebMSX

WebMSX, or simply WMSX, is a new cross platform MSX emulator designed for the Web.

WebMSX is great for displaying MSX software running inside webpages. You can launch the emulator and load ROMs, DSK and CAS images with a single link. Join friends in multiplayer games or pair programming sessions with the new NetPlay! function.

Please go to https://webmsx.org to enjoy it online!

Refer to /doc for parameters reference and URL usage examples. Refer to /release for stable release files and deployment examples.

MSX and the MSX logo are shown here as a tribute. All trademarks are property of their respective owners.

New in Release 6.0

  • 3 MSX turbo R machines (Japanese, European, American)
  • V9990 video, Superimposed and Mixed modes, or Dual Screens
  • Improved CPU Turbo emulation and control, Z80/R800 speed settings
  • Improved Kanji support, with MSX-JE input editor and dictionary
  • 6 MSX1 Palettes. Color, B&W, Green and Amber CRTs with scanlines
  • New AZERTY key mapping. Simplified hotkeys

Features

  • 12 Generic machines (MSX1, MSX2, MSX2+, MSX tR). NTSC 60Hz or PAL 50Hz
  • V9918, V9938, V9958 and V9990 video, Superimposing, Mixed, Dual Screen modes
  • PSG, SCC, SCC-I, FM-PAC, PCM, MSX-MUSIC and OPL4-Wave sound
  • Kanji support, with MSX-JE Japanese text input editor and dictionary
  • Cross platform HTML5/JS. Runs in any Browser, tested in Chrome/Firefox/Safari
  • Show MSX software running on any webpage, or with a link to the WebMSX page
  • Finally enjoy MSX games on your iPhone/iPad! Installs as a WebApp, runs offline
  • Open files from local storage, iCloud, Google Drive, Dropbox, web links
  • NetPlay! Connect several users on the same Virtual MSX machine over the internet
  • CPU and VDP Turbo modes up to 8x, with manual or software activation
  • Load Cartridge ROMs, HardDisk (Nextor), Disk and Tape images
  • Powerful Drag & Drop system for loading media files
  • Dynamically import files to any MSX disk drive, automatic image creation
  • Savestates support. Export and share Savestate files and links
  • Customizable Keyboard, Joysticks, Joykeys, and Mouse controllers
  • Customizable Touch Controls/Virtual Keyboard for mobile devices (iOS, Android)
  • Joykeys support. Emulates MSX Joysticks using Host Keyboard
  • Virtual buttons. Maps Host Joystick buttons to MSX Keyboard keys
  • Easily toggle extensions like SCC+, SCC, PAC, MegaRAM, Nextor, DoublePSG, etc.
  • Adjustable speed, Pause and Frame-by-frame advance
  • PSG/SCC/OPLL Stereo Sound simulation, configurable
  • Copy & Paste text, Screen Capture, Debug modes
  • CRT Scanlines, resizable Screen, Full Screen and Full Windowed modes
  • 6 MSX1 Palettes. Color, B&W, Green and Amber phosphor simulation
  • Javascript API for loading media and machine control

About the MSX turbo R machines

We still have some limitations on the tR and R800 emulation in this release. There is no PCM and MIDI support yet, and R800 CPU advanced timing may not be completely accurate. Also, R800 emulation hits very hard on the emulator performance, so it may not run smoothly on all devices, specially smartphones. There are options to tweak the R800 timing and clock speed from 0.5x to 2.0x.

About the V9990 Video chip

The current V9990 implementation also has some limitations on the Command Termination and Horizontal INTs. But none of the available/tested software seemed to rely on the incomplete functions.

About the light C-BIOS version

The light version with only C-BIOS ROMs can be found at: https://webmsx.org/cbios

About the NetPlay! feature

WebMSX 5.0 brings NetPlay!, in which any number of users may connect and control the same virtual MSX machine. To access the feature, open the NetPlay! control dialog available on the System Menu (Power button).

One user must be the "Server" and start a NetPlay! Session. Just choose a name for the Session, or let the emulator generate it randomly, then hit "START". Once the Session is started and active, other users may join the Session simply by entering the same Session name and hitting "JOIN". All users connected have complete control over the machine, except that only the Server user may load/change media files (ROMs, Disks, etc). All features of the emulator work during NetPlay! Any Client user may leave the Session at any time, but only the Server user may end the Session completely.

Be careful not to make your Session name public! Anyone that knows your Session name will be able to join it while its active. Send the session name only to people you want to invite. Another way of sharing your Session to users is sending them a link that will open the emulator and join the session automatically. In the NetPlay! dialog, once you are Hosting a Session, there will be a link button on the upper right, that will generate the link and copy it to your clipboard.

IMPORTANT: NetPlay! performance is completely dependent on the network quality. The lower the network latency between users, the better. Higher bandwidths with higher latencies won't help much. The Client may need some time to find and connect do the Server. It uses a specialized P2P protocol, and tries to use STUN to traverse NATs/routers so users don't have to worry about IPs and opening ports. Use at your own risk! :-)

To make all this work seamlessly, WebMSX uses modern Web technologies including WebRTC, which are supported by all major browsers and platforms. Unfortunately, those technologies may still not be available on Apple iOS, so NetPlay! may not work on those devices.

About the Nextor Hard Disk Drive

To make the Hard Disk Drive available, you must first activate the Hard Drive Extension, through the Extensions Menu on the user interface, or by using the respective Presets. The Hard Disk device may be placed "before" the Floppy Drives, so it will appear on the system as Drive A, or "after" the Floppy Drives, so it will appear as Drive C. The position depends on which Slot the Extension is activated on. If using Presets, there are two available: HARDDISK will place the device as Drive A, and HARDDISKC will place it as Drive C. On the Hard Drive menu (HD icon), there are options to automatically create Empty and Boot disks of several sizes. You can also load DSK images, Files or ZIPs normally.

WebMSX Configuration and Launch Options

Several parameters are available for customizing the emulator. They can be changed either directly in Javascript if you are hosting the emulator in your own page, by loading a Configuration File, or via URL Query Parameters if you are creating links or bookmarks to open the emulator, or just using it in your browser.

All parameters are in the form of properties in the global object WMSX. Just set these object properties in Javascript, or use URL Query parameter/value pairs. For example:

WMSX.ROM = "files/Game.rom";      is the same as      https://webmsx.org?ROM=files/Game.rom

To load an external Configuration File, set the CONFIG_URL parameter. The config file must be a valir JSON object. This object's properties will be merged with the standard configuration properties. For example:

WMSX.CONFIG_URL = "files/CustomMachines.json";     or     https://webmsx.org?CONFIG_URL=files/CustomMachines.json

All emulator Savestates, Settings and Preferences can be stored in multiple isolated spaces, using the Environments feature. Just set the ENVIRONMENT parameter (or E for short) to any number in the 1..99 range. For example:

WMSX.ENVIRONMENT = 2;     or     https://webmsx.org?E=2

Another important concept is the use of configuration Presets. Some configurations are a bit complicated and may require setting various parameters in conjunction. For those cases, its easier to use a Preset that will automatically set all the relevant parameters for a specific task. You may specify any number of Presets to be used by setting the PRESETS parameter (or P for short) with a comma separated list of the Preset names to apply. For example:

WMSX.PRESETS = "RAM128, NODISK";     or     https://webmsx.org?P=RAM128,NODISK

IMPORTANT: Any parameter setting via Javascript must be done AFTER importing the webmsx.js file.

Media Loading

The emulator can be set to automatically load files like ROMs, DSK and CAS images. Additionally, files can be loaded and automatically injected into any of the Disks Drives, without having to first create an image. Image files may be compressed in ZIP or GZIP formats. If several Disk images are found in a ZIP file, all of them (up to 10) will be loaded in the Drive Stack. Available parameters:

Parameter Function Shortcut for URL form
CARTRIDGE1_URL URL of ROM image file to load in Slot 1 ROM, CART1
CARTRIDGE2_URL URL of ROM image file to load in Slot 2 CART2
CARTRIDGE1_FORMAT Force ROM Format for Cartridge in Slot 1 ROM_FORMAT, CART1_FORMAT
CARTRIDGE2_FORMAT Force ROM Format for Cartridge in Slot 2 CART2_FORMAT
DISKA_URL URL of Disk image file to load in Drive A: DISK, DISKA
DISKB_URL URL of Disk image file to load in Drive B: DISKB
HARDDISK_URL URL of Disk image file to load in the Hard Drive HARDDISK
DISKA_FILES_URL URL of file or ZIP (for several files) to load in Drive A: DISK_FILES, DISKA_FILES
DISKB_FILES_URL URL of file or ZIP (for several files) to load in Drive B: DISKB_FILES
HARDDISK_FILES_URL URL of file or ZIP (for several files) to load in Hard Drive HARDDISK_FILES
TAPE_URL URL of Tape image file to load TAPE
STATE_URL URL of SaveState file to load STATE, SAVESTATE
AUTODETECT_URL URL of file to load with media auto-detection AUTODETECT, AUTO, ANY

ROM Format (or Mapper Type)

The ROM Format is auto-detected. To force a format, set the CARTRIDGE1_FORMAT and CARTRIDGE2_FORMAT parameters, or access the User Interface. You can also put the format specification in the ROM file name, between brackets. Example: Game [KonamiSCC].rom

Valid Formats

Normal, Mirrored, NotMirrored, ASCII8, ASCII16, Konami, KonamiSCC, KonamiSCCI, ASCII8SRAM2, ASCII8SRAM8, ASCII16SRAM2, ASCII16SRAM8, MegaRAM, GameMaster2, KoeiSRAM8, KoeiSRAM32, Wizardry, FMPAC, FMPAK, MSXDOS2, Majutsushi, Synthesizer, RType, CrossBlaim, Manbow2, HarryFox, AlQuran, AlQuranDecoded, Halnote, SuperSwangi, SuperLodeRunner, Dooly, Zemina80in1, Zemina90in1, Zemina126in1, MSXWrite, KonamiUltimateCollection

Choosing a Machine

There are 12 different generic machines. The default machine is the MSX2+, and the emulator will try to auto-detect your region. You can ask for a specific machine by setting the MACHINE parameter (or M for short) with the respective Machine ID:

Machine Machine ID Specific Machine Machine ID
MSX tR Auto-detection MSXTR MSX tR American (NTSC 60Hz) MSXTRA
MSX tR European (PAL 50Hz) MSXTRE
MSX tR Japanese (NTSC 60Hz) MSXTRJ
MSX2+ Auto-detection MSX2P MSX2+ American (NTSC 60Hz) MSX2PA
MSX2+ European (PAL 50Hz) MSX2PE
MSX2+ Japanese (NTSC 60Hz) MSX2PJ
MSX2 Auto-detection MSX2 MSX2 American (NTSC 60Hz) MSX2A
MSX2 European (PAL 50Hz) MSX2E
MSX2 Japanese (NTSC 60Hz) MSX2J
MSX1 Auto-detection MSX1 MSX1 American (NTSC 60Hz) MSX1A
MSX1 European (PAL 50Hz) MSX1E
MSX1 Japanese (NTSC 60Hz) MSX1J

It's possible to define additional Custom Machines, by loading an external Configuration File (CONFIG_URL parameter). Contact the author for details!

Enabling Extensions

The emulator supports several Extensions, or optional components that can be turned on/off. Some are in the form of expansion cartridges that can be inserted in either Slot 1 or 2. We use Presets to make configuring Extensions easier:

Extension Default in Machine Presets
Hard Disk interface (Nextor) -- HARDDISK, HARDDISKC, NOHARDDISK
Floppy Disk interface with 2 drives All DISK, NODISK
Standard RAM Mapper, adjustable size MSX2 or higher RAM128..RAM4096, RAMNORMAL
Kanji Characters with MSX-JE Japanese MSX2 or higher KANJI, NOKANJI
V9990 Video -- V9990
MSX-MUSIC sound with BASIC extension MSX2 or higher MSXMUSIC, NOMSXMUSIC
OPL4 Wave sound -- OPL4
Double PSG -- DOUBLEPSG
SCC-I Sound Cartridge with 128K RAM -- SCCI, SCCI2 (in Slot 1/2)
SCC Sound Cartridge -- SCC, SCC2 (in Slot 1/2)
PAC SRAM Cartridge -- PAC, PAC2 (in Slot 1/2)
MegaRAM Cartridge -- MEGARAM, MEGARAM2 (in Slot 1/2)

Loading BASIC files and Typing commands after launch

The emulator can be set to automatically Run/Load BASIC programs after launch, or type any commands or text in the BASIC prompt. NOTE that these are not necessary for AUTOEXEC.BAS and AUTOEXEC.BAT files, or if you have loaded a Tape Image file (in which case the emulator will automatically detect and Run the first program in the Tape). Available parameters:

Parameter Action
BASIC_RUN Run the specified file
BASIC_LOAD Load the specified file
BASIC_BRUN Run the specified bynary file
BASIC_BLOAD Load the specified bynary file
BASIC_TYPE Type the specified text
BASIC_ENTER Type the specified text then hit ENTER

Controlling boot speed and automatically pressing keys at boot time

Parameter Action
FAST_BOOT Boot at max. speed
BOOT_KEYS Keys to keep pressed at every boot, comma separated
BOOT_KEYS_ONCE Same as above, but only on first boot (do not use both)
BOOT_KEYS_FRAMES Optional number of frames for Boot Keys

Launch URL Examples

WebMSX is great for displaying MSX software in the web. With a simple URL, you can launch the emulator and automatically load and run anything. You may combine several settings and media loading options in a single link. Here are some examples:

  • To load a game in ROM format:
https://webmsx.org?ROM=https://gamesarchive.org/Goonies.rom
  • To load a game in a ZIPped Disk Image and insert a SCC+ Sound Cartridge:
https://webmsx.org?DISK=https://gamesarchive.org/SDSnatcher.zip&PRESETS=SCCI
  • To launch an European MSX1 machine, loading a Disk image and then run a BASIC program:
https://webmsx.org?MACHINE=MSX1E&DISK=https://basicmuseum.org/Demos.dsk&BASIC_RUN=Bubbles.bas

Presets Reference

Preset Description
HARDDISK, HARDDISKC, NOHARDDISK Hard Drive Extension
DISK, DISKA, NODISK Floppy Drives Extension
RAMMAPPER, RAM128 - RAM4096, RAMNORMAL RAM Mapper Extension & sizes
V9990 V9990 Video Extension
KANJI, NOKANJI Kanji ROM Extension
MSXMUSIC, NOMSXMUSIC, DOUBLEPSG, OPL4 Sound Devices Extensions
SCCI, SCCI2, SCC, SCC2 SCC+/SCC Cartridge (in Slot 1/2)
PAC, PAC2 PAC SRAM Cartridge (in Slot 1/2)
MEGARAM, MEGARAM2, MEGARAM256 - MEGARAM2048 MegaRam Cartridge (in Slot 1/2) & sizes
VSYNCON, VSYNCOFF, VSYNCDISABLED VSync options
ALLSTEREO, ALLSTEREO2 Stereo simulation for all devices (default/variation)
PSGSTEREO, PSGSTEREO2 PSG Stereo simulation (default/variation)
SCCSTEREO, SCCSTEREO2 SCC Stereo simulation (default/variation)
OPLLSTEREO, OPLLSTEREO2 OPLL Stereo simulation (default/variation)
ALTSLOTCONFIG Alternate Slot Configuration. RAM at Primary Slot 3
BOOSTED Boosted Machine with HardDisk and CPU/VDP 3x Turbo

Parameters Reference

Parameter (+ new) Default Description
ENVIRONMENT 0 Emulator Environment. Isolate Savestates & Preferences. 1..99
CONFIG_URL -- Configuration file to merge. Processed before URL parameters
MACHINE -- Machine Type. Leave blank for auto-detection
PRESETS -- Configuration Presets names to apply, comma separated
CARTRIDGE1_URL -- URL of ROM image file to load in Slot 1
CARTRIDGE2_URL -- URL of ROM image file to load in Slot 2
CARTRIDGE1_FORMAT -- ROM Format for Cartridge in Slot 1
CARTRIDGE2_FORMAT -- ROM Format for Cartridge in Slot 2
DISKA_URL -- URL of Disk image file to load in Drive A:
DISKB_URL -- URL of Disk image file to load in Drive B:
HARDDISK_URL -- URL of Disk image file to load in the Hard Drive
DISKA_FILES_URL -- URL of file or ZIP (for several files) to load in Drive A:
DISKB_FILES_URL -- URL of file or ZIP (for several files) to load in Drive B:
HARDDISK_FILES_URL -- URL of file or ZIP (for several files) to load in Hard Drive
TAPE_URL -- URL of Tape image file to load
STATE_URL -- URL of SaveState file to load
AUTODETECT_URL -- URL of file to load with media auto-detection
SLOTXY_URL -- URL of ROM file to load in Slot X-Y (X,Y are numbers). Omit Y for primary slot
SLOTXY_FORMAT -- ROM Format for Slot X-Y loaded above
NETPLAY_JOIN -- Join NetPlay! Session automatically
NETPLAY_NICK -- NetPlay! Nickname, optional
BASIC_RUN -- Run the specified file name
BASIC_LOAD -- Load the specified file name
BASIC_BRUN -- Run the specified binary file name
BASIC_BLOAD -- Load the specified binary file name
BASIC_TYPE -- Type the specified text
BASIC_ENTER -- Type the specified text then hit ENTER
BOOT_KEYS -- Keys to keep pressed at every boot, comma separated
BOOT_KEYS_ONCE -- Same as above, but only on first boot (do not use both)
BOOT_KEYS_FRAMES -1 Number of frames for Boot Keys. -1: auto; > 0: frames
FAST_BOOT 0 Number of frames for Fast Boot. 0: off; 1: auto (same as Boot Keys frames); > 1: number of frames
VDP_TYPE -1 VDP Chip. -1: auto; 1: V9918; 2: V9938; 3: V9958
+ VDP_PALETTE 2 MSX1 Palette. 0: WebMSX Original; 1: V9918; 2: V9928; 3: V9938; 4: Toshiba; 5: Fujitsu FM-X
RTC_ACTIVE -1 RTC Chip. -1: auto; 0: not present; 1: present
RAMMAPPER_SIZE 512 RAM Mapper size when active. 64, 128, 256, 512, 1024, 2048, 4096, in KB
RAMNORMAL_SIZE 64 Normal RAM size when active. 16..64, in KB
VOL 1.0 Master Volume factor
SPEED 100 Default emulation speed (in %)
SCREEN_ELEMENT_ID "wmsx-screen" HTML Element ID to place the Emulator Screen
ALLOW_URL_PARAMETERS true Allows overriding any parameters via URL query parameters
AUTO_START true Auto-Start the emulator as soon as ready
AUTO_POWER_ON_DELAY 1200 Auto-Power-ON after specified msecs. -1: no Auto-Power-ON
MEDIA_CHANGE_DISABLED false Block user from changing Media (Cartridges, Disks, etc)
SCREEN_RESIZE_DISABLED false Block user from changing Sreen size
SCREEN_FULLSCREEN_MODE -1 FullScreen mode. -2: disabled; -1: auto; 0: off; 1: on (Full Screen); 2: on (Full Windowed)
SCREEN_FILTER_MODE -3 Screen CRT Filter level. -3: user set (default auto); -2: browser default; -1: auto; 0..3: smoothing level
SCREEN_CRT_SCANLINES -1 Screen CRT Scanlines. -1: user set (default off); 0: off; 1..10: level
SCREEN_CRT_PHOSPHOR -1 Screen CRT Phosphor Effect. -1: auto (off); 0: off; 1: on
SCREEN_DEFAULT_SCALE -1 Screen size. -1: auto; 0.5..N in 0.1 steps
SCREEN_DEFAULT_ASPECT 1.14 Screen Aspect Ratio (width) in 0.1 steps
SCREEN_CONTROL_BAR 1 Screen Bottom Bar controls. 0: on hover; 1: always
SCREEN_FORCE_HOST_NATIVE_FPS -1 Force host native video frequency. -1: auto-detect. Don't change! :-)
SCREEN_VSYNC_MODE -2 VSync mode. -2: user set (default auto); -1: disabled; 0: off; 1: auto (on when available)
+ SCREEN_VIDEO_OUT -1 Video output. -1: auto; 0: Internal VDP; 1: External V9990; 2: Superimposed; 3: Mixed; 4: Dual (main: Internal); 5: Dual (main: V9990)
+ SCREEN_COLORS 0 CRT color type. 0: Color; 1: B&W; 2: Green Phosphor; 3: Amber Phosphor
AUDIO_MONITOR_BUFFER_BASE -3 Audio buffer base size. -3: user set (default auto); -2: disable audio; -1: auto; 0: browser default; 1..6: base value. More buffer = more delay
AUDIO_MONITOR_BUFFER_SIZE -1 Audio buffer size. -1: auto; 256, 512, 1024, 2048, 4096, 8192, 16384: buffer size. More buffer = more delay. Don't change! :-)
AUDIO_SIGNAL_BUFFER_RATIO 2 Internal Audio Signal buffer based on Monitor buffer
AUDIO_SIGNAL_ADD_FRAMES 3 Additional frames in internal Audio Signal buffer based on Monitor buffer
+ R800_CLOCK_MODE 0 R800 CPU Clock. 0: auto; (0..2]: R800 CPU clock multiplier
+ R800_TIMING 1 Precise R800/S1990 timings. 0: off, 1: on; 2: VDP waits only. Turn off for faster and lighter emulation
Z80_CLOCK_MODE 0 Z80 CPU Clock. 0: auto (soft-turbo possible); (0..8]: CPU clock multiplier
VDP_CLOCK_MODE 0 VDP Command Engine Clock. 0: auto (soft-turbo possible); (0..8]: Engine clock multiplier; 9: instantaneous
Z80_SOFT_TURBO_MULTI 1.5 Z80 CPU clock multiplier when in AUTO mode and activated by software. 1..8: multi
VDP_SOFT_TURBO_MULTI 1 VDP Command Engine clock multiplier when in AUTO mode and activated by software. 1..9: multi
+ CPU_SOFT_TURBO_AUTO_ON 0 Automatically activate the CPU Soft Turbo when supported by machine. 0: off, 1: on
+ CPU_FAKE_TR_TURBO -1 Simulated tR CHGCPU Turbo activation. -1: auto; 0: off; 1: on. Auto ON for 2+, never for tR
+ CPU_PANA_TURBO -1 Simulated Panasonic Turbo activation. -1: auto; 0: off; 1: on. Auto ON for 2+, never for tR
JOYSTICKS_MODE 0 Joysticks (on Host) controls. -1: disabled; 0: auto; 1: auto (swapped)
JOYKEYS_MODE -1 JoyKeys controls. -1: disabled; 0: enabled at port 1; 1: enabled at port 2; 2: enabled at both ports; 3: enabled at both ports (swapped)
MOUSE_MODE -1 Mouse controls. -1: disabled; 0: auto; 1: enabled at port 1; 2: enabled at port 2
TOUCH_MODE 0 Touch controls. -1: disabled; 0: auto; 1: enabled at port 1; 2: enabled at port 2
+ MOBILE_MODE 0 Forced Mobile interface mode. -1: disabled; 0: auto; 1: enabled
DEBUG_MODE 0 Debug Modes. 0: off; 1..7: mode. Don't change! :-)
SPRITES_DEBUG_MODE 0 Sprites Debug Modes. 0: off; 1: unlimited; 2: no collisions; 3: both. May cause problems :-)
KEYBOARD_JAPAN_LAYOUT 1 Japanese keyboard layout. 0: ANSI, 1: JIS
ROM_MAX_HASH_SIZE_KB 5120 Maximum ROM size for Hash calculation
HARDDISK_MIN_SIZE_KB 720 Minimum file size to be accepted as HardDisk image (besides all valid Floppy formats)
MEGARAM_SIZE 2048 MegaRAM size in KB
DISK_ROM_START_PAGE 0 Change starting page for ROMs > 16KB when format is DiskPatch. 0..1
PSG_VOL "f" PSG Volume adjust: 0..f (hex digit). Set globally or for each channel (4 values)
PSG_PAN "8" PSG PanPot adjust: 0; 1..8..f (hex digit). Set globally or for each channel (4 values)
SCC_VOL "f" SCC Volume adjust. Same as above (5 values)
SCC_PAN "8" SCC PanPot adjust. Same as above (5 values)
OPLL_VOL "f" OPLL Volume adjust. Same as above (14 values)
OPLL_PAN "8" OPLL PanPot adjust. Same as above (14 values)
PAGE_BACK_CSS -- CSS to modify page background color. Applied to the body element

About

WebMSX - Online MSX Emulator

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • HTML 85.8%
  • JavaScript 13.9%
  • Assembly 0.3%