JBit

Tutorial

English | Italian | Spanish

Traducido por Facundo Couzo

VM

JBit es un entorno de desarrollo íntegro, y es más complejo que una aplicación típica para teléfonos móbiles. Este tutorial te permitirá comenzar a utilizar JBit

Lo primero que debes comprender es que, cuando escribes un programa usando JBit, no lo escribes para tu teléfono móvil, sino para la Máquina Virtual de JBit (Edición MicroIO), o VM, por sus siglas en inglés

Aquí tienes una imagen del VM, y puedes ver que parece un viejo teléfono móvil. Aunque el VM parezca un telefono, no lo es, ya que no puedes recibir o realizar llamadas, o mensajes de texto con él. Inclusive, la pantalla solo puede mostrar una matriz de 10x4 carácteres, y el teclado solo posee las teclas estándar (0-9, * y #)

Si no puede usarse como teléfono, para que sirve el VM? Bueno, en sí el VM no hace mucho. pero aprendiendo como programarlo, puedes comprender como funcionan las computadoras. Las computadoras son herramientas complejas y su núcleo está escondido tras múltiples capas de abstracción, y ese núcleo no es mucho más complejo que el VM.

Main Menu (Editor)

Otra cosa que debes comprender es la diferencia entre el VM y JBit. JBit incluye al VM, pero no solo eso, también incluye herramientas para ayudarte a editar y gestionar programas para el VM.

En realidad, no puedes acceder al VM hasta que hagas un programa para el. El VM en sí está vacio y no tiene una interface con la que puedas jugar. Por lo tanto, nuestra primera tarea será crear un pequeño programa, para que podamos ver al VM.

Selecciona Editor De la lista.

New

El editor necesita saber el tamaño del programa. En esta etapa, no nos importa el tamaño, así que simplemente confirmamos 4 páginas de código (code pages) y 3 páginas de datos (data pages).

Selecciona aceptar (OK).

Algunos teléfonos poseen una tecla mapeada a aceptar, mientras que en otros, aceptar es accesible ingresando a un menú. Si no ves la pantalla para cambiar tamaño (Size (New)), probablemente sea porque ya tienes un programa cargado y deberías resetear JBit.

Empty Prog.

Ahora deberías ver una matriz de ceros. Este es un programa. Después volveremos a esto. Por ahora, iremos directo al VM.

Selecciona depurar (Debug).

CPU (1)

Aquí está el VM. Notarás que no se ve como la imagen anterior. Esto es porque ahora estás dentro del VM!

Presiona # para cambiar a la vista exterior.

Display (Empty)

Ahora estas viendo a la visualización del VM. No hay razón de mostrar el teclado, ya que el teclado de tu teléfono funciona como el teclado del VM.

Aquí hay un pequeño problema. Sí comenzaramos el VM directamente, este se hubiera detenido inmediatamente, ya que el programa está vacío. En cambio, hemos comenzado el VM en un estado detenido, que nos permite inspeccionarlo. En este modo de operación, es más comun mirar la pantalla que usar al teclado, así que, por ahora, el teclado de tu teléfono no está siendo usado como el teclado del VM. En su lugar, el teclado del teléfono es usado para volver a la vista interior

Presiona # otra vez para volver a la vista interior.

CPU (BRK)

Veamos que hay dentro del VM.

Probablemente ya habrás oido hablar del CPU (Unidad de Procesamiento Central), ya que es uno de los criterios a tener en cuenta al elegir una computadora. El CPU que usa el VM es basicamente un 6502, un CPU popular durante los años 70 y 80. Es más pequeño y lento, pero desde un punto de vista teórico, no menos capaz que un CPU moderno.

Comprender el funcionamiento de un CPU es el sentido de usar JBit, y puede tomar un tiempo. Podemos comenzar con esto: el CPU es un agente que actúa por nosotros en un mundo virtual. Antes de permitir actuar al CPU por nosotros, vamos a jugar un poco con este mundo virtual.

Presiona 0 para cambiar al modo memoria (MEM).

Memory (Empty)

A diferencia del mundo real, donde somos libres de ubicar objetos donde se nos plazca, en este mundo virtual, los objetos se ubican en celdas y las celdas se ubican en una única fila.

Además, a diferencia del mundo real, en donde hay una gran variedad de objetos, en este mundo virtual, hay solo una clase de objeto, el byte, un pequeño número entero entre 0 y 255.

Por último, a diferencia del mundo real, este mundo virtual es finito. Hay exáctamente 65536 celdas. Para poder gestionar esta larga secuencia de celdas, la dividimos en 256 segmentos llamados páginas (pages) de 256 celdas cada uno. Esto también nos permite referirnos a la ubicación de una celda usanfo 2 bytes: el número de la página (de 0 a 255), y un segmento (offset) dentro de esa página (de 0 a 255). este par de bytes es llamado la dirección (address) de una celda, y se escribe como dos números separados por dos puntos. Por ejemplo, la primera celda tiene una dirección 0:0, la última tiene una dirección 255:255, y la 260 tiene una dirección 1:3 (la cuarta celda de la segunda página). Normalmente vamos a escribir la celda página:segmento para referirnos a la celda en la dirección página:segmento.

El modo memoria (MEM) te permite observar este mundo virtual. Para aprovechar al máximo el pequeño display de un teléfono móvil, las celdas se muestran en una matriz, pero deberías tener siempre en mente que en realidad son una sola fila.

La celda actual (la que estamos viendo en este momento) esta marcada por el cursor. El cursor puede ser movido usando 4 (o izquierda) para ir a la celda anterior, y 6 (o derecha) para ir a la siguiente. También puedes usar 2 (o arriba) and 8 (o abajo) para mover el cursor.

mueve el cursor hasta la celda 3:25 y selecciona Edit.

Edit

Esta pantalla te permite cambiar el contenido de una celda.

Introduce 56 en el campo valor (Value) y selecciona aceptar (OK).

Memory (56)

El contenido de la celda ha cambiado. Mueve el cursor más abajo hasta que la celda 3:25 no sea visible (por ejemplo, hasta que alcances la celda 3:50) y vuelve a subir, puedes ver que la celda mantuvo el valor que le pusiste. La celda 3:25, como la mayoría de las celdas es una celda de memoria, una celda que mantiene el valor que le asignan.

Selecciona GoTo.

GoTo

Esta pantalla te permite mover el cursor a una celda específica.

Ingresa 2 en el campo página (Page), ingresa 40 en el campo segmento (Offset) y selecciona aceptar (OK).

Memory (IO)

Las celdas en la página 2 no son celdas de memoria. En cambio, son vínculos a un componente llamado el chip de Entrada/Salida (IO chip). En particular, las celdas de 2:40 a 2:79 están conectadas al display, de esta manera:

     0  1  2  3  4  5  6  7  8  9
 40  .  .  .  .  .  .  .  .  .  .
 50  .  .  .  .  .  .  .  .  .  .
 60  .  .  .  .  .  .  .  .  .  .
 70  .  .  .  .  .  .  .  .  .  .

Poniendo un byte de 32 a 126 en una de estas celdas hace que un caracter aparezca en la pantalla, de acuerdo a la siguiente tabla:

     0  1  2  3  4  5  6  7  8  9
 30           !  "  #  $  %  &  '
 40  (  )  *  +  ,  -  .  /  0  1
 50  2  3  4  5  6  7  8  9  :  ;
 60  <  =  >  ?  @  A  B  C  D  E
 70  F  G  H  I  J  K  L  M  N  O
 80  P  Q  R  S  T  U  V  W  X  Y
 90  Z  [  \  ]  ^  _  `  a  b  c
100  d  e  f  g  h  i  j  k  l  m
110  n  o  p  q  r  s  t  u  v  w
120  x  y  z  {  |  }  ~

Memory (88)

Selecciona editar (Edit), ingresa 88 en el campo valor (Value) y selecciona aceptar (OK).

Display (X)

Presiona # para cambiar a la vista exterior.

Puedes ver que el carácter X es visible en la esquina superior izquierda de la pantalla. En teléfonos con pantallas más grandes, el carácter estará más centrado, ya que la pantalla del VM es menor que la pantalla del teléfono.

Ahora que tenemos una mejor idea de como "actuar en un mundo virtual", ya podemos darle otra mirada al CPU.

Presiona # otra vez para volver a la vista interior y 0 para cambiar a la vista de CPU.

CPU (BRK)

el CPU puede realizar un número limitado de acciones básicas, llamadas instrucciones (instructions) u operaciones (operations), por ejemplo: leer un byte de una celda, escribir un byte en una celda, sumar dos bytes entre sí, etc...

Un programa es basicamente un archivo que indica una secuencia de operaciones que el CPU debe realizar para producir un comportamiento deseado.

El CPU busca la operación a realizar desde las celdas, empezando por 3:0. Lo que para nosotros es solo un número como cualquier otro, para el CPU tiene un significado específico. Por ejemplo, 0 significa BRK (BReaK, o quiebre) para el CPU. El nombre BRK significa que en un 6502 de verdad, el programa se suspendería. Esta es una de las pocas diferencias entre un 6502 real y el VM. En el VM, BRK termina el programa.

La memoria del CPU se almacena en registros (registers), en lugar de celdas. Por ahora solo veremos algunos de ellos. Primero esta el registro contador del programa PC, (Program Counter). Tiene un tamaño de 2 bytes y contiene la dirección de la celda que posee la próxima operación a realizar. Después se encuentran tres registros de 1 byte de tamaño cada uno. Estos son: acumulador A (Accumulator), X e Y.

Memory (232)

Presiona 0 para cambiar al modo memoria MEM.

Escribe 232 en la celda 3:0. Esto es: selecciona GoTo, ingresa 3 en el campo página (Page), ingresa 0 en el campo segmento (Offset), selecciona OK, seleccina Edit, ingresa 232 en el campo valor (Value) y selecciona aceptar (OK).

Presiona 0 para volver a la vista de CPU.

CPU (INX)

para el CPU, 232 significa INX (INcrement X). INX hace que el registro X sea aumentado en 1. Si el registro contiene 255, es devuelto a 0.

Presiona 1 para avanzar un paso (permitirle al CPU realizar una operación).

CPU (BRK - 2)

Puedes ver que la operación se ha realizado: el registro X ahora contiene 1 y el PC apunta a la siguiente celda (la celda 3:1, que contiene la siguiente operación a realizar).

Podriamos cambiae el contenido de la celda 3:1 y repetir el proceso otra vez, pero esta no es la mejor manera de hacerlo. Para escribir secuencias de instrucciones es mejor usar el Editor.

Presiona 1 para avanzar un pase y terminar el programa.

Halted

Tienes una última oportunidad de mirar la pantalla, antes de apagar el VM y volver al Editor

Seleccina finalizar (End).

Empty Prog.

El Editor es un editor modal, esto significa que el efecto de presionar una tecla depende del modo de operación actual del editor. Hay dos mayores modos de operación: navegación (NAV) y edición (EDT), combinados con dos modos menores de operación: memoria (MEM) y ensamblador (ASM).

El modo NAV MEM se comporta como la vista de memoria (MEM) antes descripta. Como antes, puedes mover el cursor usando 4 (o izquierda), 6 (o derecha), 2 (o arriba) y 8 (o abajo). La principal diferencia es que no puedes alcanzar las celdas más allá del límite del programa. Esto es porque, cuando escribes un programa, no editas la memoria del VM, si no que simplemente escribes una plantilla de bytes que luego serán usados para inicializar la memoria.

Prog. (2 232 2 EDT)

Asegurate que el cursor esté en 3:0 y presiona 5 (o aceptar en algunos teléfonos).

El modo EDT MEM permite editar los bytes del programa "en el lugar", es decir, sin abrir una nueva pantalla.

Presiona 2, *, 2, 3, 2 y 2.

Nota lo siguiente:

  1. No estás limitado a escribir un byte, puedes escribir una secuencia completa de bytes.
  2. Para bytes con menos de tres dígitos, puedes moverte al siguiente byte presionando *.
  3. Al insertar bytes con exáctamente tres bytes, el cursor se mueve al siguiente byte automáticamente.

Sí cometes un error tipeando la secuencia, puedes seleccionar cancelar (Cancel) para limpiar el byte actual. Sí el byte actual está vacío, presionar cancelar desplaza el cursor al byte anterior. Sí alcanzas el primer byte y presionas cancelar, vuelves al modo NAV MEM sin realizar cambios.

Presiona aceptar (OK) para confirmar los cambios y volver al modo NAV MEM.

Prog. (2 232 2 NAV)

Los primeros tres bytes del programa deberían ser: 2, 232, y 2. Tal vez reconozcas 232 como INX, pero que ocurre con 2?

Presiona #.

Prog. (ASM - Invalid)

El modo NAV ASM te permite ver el programa tal como sería interpretado por el CPU. Puedes mover el cursor usando 2 (o arriba) y 8 (o abajo) para recorrer la lista, pero no puedes presionar 5 para editar aquí.

Así que 2 significa ??? para el CPU. Eso no es de mucha ayuda. Corramos el VM (de la forma correcta esta vez) para ver que pasa.

Presiona *.

INV.OP.

Esto es lo que sucedió:

  1. Se encendió el VM.
  2. El programa fue copiado a las celdas de memoria del VM.
  3. El CPU leyó la celda 3:0 para obtener la operación a realizar.
  4. Como 2 carece de significado para el CPU, el VM se detuvo con un error.

INV.OP. Es la abreviación de codigo de operación inválido (invalid opcode). El código de operación es el byte que identifica que clase de operación de va a realizar. Algunos opcodes (como 232) tienen sentido para el CPU, mientas que otros (como 2), no lo tienen.

Selecciona Finalizar (End) para volver al Editor, y entonces presiona # para cambiar al modo NAV MEM.

Prog. (2 232 2 NAV)

Ubica el cursor en 3:0, presiona 5 para cambiar al modo EDT MEM y presiona # para cambiar al modo EDT ASM.

Prog. (EDT)

El modo EDT ASM te permite buscar opcodes válidos.

Presiona 5 (jkL), 3 (Def) y 2 (Abc).

Prog. (LDA #n)

Antes de continuar, permitame decirlo con otras palabras:

232 significa INX para el CPU
Realmente, 232 no significa nada para el CPU, ya que este no piensa:
Cuando el CPU lee el código de operación (opcode) 232 de una celda, incrementa el registro X.

La etiqueta de tres letras INX es llamada un mnemotécnico y sirve para recordarle al programador que hace el CPU.

Veamos otros dos opcodes: 169 y 173.

169. Cuando el CPU lee el opcode 169 desde una celda, reemplaza el contenido del acumulador con el contenido de la celda directamente después de la que contiene el opcode.
173. Cuando el CPU lee el opcode 173 desde una celda, reemplaza el contenido del acumulador con el contenido de una celda específica. La dirección de esta celda se obtiene tomando el segmento de la celda siguiente al opcode y la página de la celda siguiente a esta.

Es algo complejo, pero ahora voy a dar algunos ejemplos. Lo más importante ahora es ver la similitud entre estos opcodes: en ambos el contenido del acumulador es reemplazado. El mnemónico de estos opcodes es LDA, cargar acumulador (LoaD Accumulator).

Aquí hay un ejemplo para el opcode 169:

169 65

Nota que, a diferencia de BRK y INX, un byte no es suficiente para especificar el comportamiento del CPU. Sí queremos que el CPU reemplace el contenido del acumulador, debemos especificar el nuevo contenido (65 en este caso). En otras palabras: la operación que empieza con 169 mide dos bytes, y el segundo byte, el operando (operand) especifica el nuevo contenido del acumulador.

Y aquí hay un ejemplo para el opcode 173:

173 40 2

En este caso, la operación mide tres bytes, y los ultimos dos bytes (el operando), especifican la dirección de la celda donde se encuentra el valor que va a tomar el acumulador. En este caso, la celda sería 2:40. Notarás que el orden esrá invertido, pero rápidamente te acostrumbarás a ello.

Sí miras a las dos secuencias de bytes anteriores, verás que no está claro que hacen algo parecido (reemplazar el contenido del acumulador). Más aún, en un programa largoo compuesto de múltiples operaciones, es difícil encontrar donde empiezan las operaciones y comprobar si pusiste el número correcto de bytes para operandos.

Considere esta secuencia:

169 40 2

Tal vez quisiste cargar el acumulador con el contenido de la celda 2:40. Pero, por supuesto, el CPU no puede adivinar que querías, simplemente cargaría el acumulador con 40 y detendría el VM porque 2 no es un opcode válido.

El lenguaje de ensamblador es un método efectivo de presentar los bytes de un programa. Cada operación está claramente representada en cada línea, sin importar si mide 1, 2 o 3 bytes. Su comportamiento está definido sin ambigüedades en cada mnemónico, y, cuando es necesario, en su operando. El operando en sí está formateado usando un patrón riguroso. Este patrón es una forma compacta de expresar la segunda parte de las secuencias anteriores, o como se dice en ensamblador de 6502, el mode de direccionamiento (addressing mode).

Vista de memoria Vista de ensamblador Explicación
169 65 LDA #65 Carga el acumulador [LDA] con la constante [#n] 65
173 40 2 LDA 2:40 Carga el acumulador [LDA] con el contenido de la celda [n:n] 2:40

Los modos de direccionamiento son #n y n:n, donde n significa número.

la hoja de referencia JBit-QS.pdf contiene la lista completa de los modos de direccionamiento del CPU. No es necesario que los entiendas todos con solo la pequeña descripción de la referencia, pero igualmente puedes obtener algo de información de la forma en que se ven: el número de letras minúsculas del modo de direccionamiento es el número de bits extra que necesita la operación. Por ejemplo, El modo de direccionamiento n:n,X necesita dos bytes extra después del opcode.

El lenguaje ensamblador, como cualquier otro lenguaje de programación es un lenguaje formal, y a diferencia de los lenguajes naturales, los detalles importan. Por ejemplo, En español, puedes tener un error de puntuación, perolo mismo puedes ser comprendido. En lenguaje ensamblador, hasta la puntuación debe ser perfecta. La operación LDA #65 (169 65) y LDA 65 (165 65) Son completamente diferentes (la segunda es una versión mas corta y rápida de LDA 0:65).

Selecciona LDA #n de la lista. el número 169 es insertado, el cursor se mueve a la siguiente celda, y el modo es cambiado de vuelta a EDT MEM.

Prog. (169 65 EDT)

Presiona 6, 5 y * para insertar el operando.

Presiona # para cambiar al modo EDT ASM.

Presiona 7 (pqrS), 8 (Tuv) y 2 (Abc).

Prog. (STA n:n)

STA es el mnemónico de almacenar acumulador (STore Accumulator), y es el opuesto de LDA: reemplaza el contenido de una celda con el contenido del acumulador.

la hoja de referencia JBit-QS.pdf contiene la lista completa de mnemónicos del CPU. De nuevo, no es necesario que los comprendas todos con la pequeña descripción contenida en la referencia, pero aún sin ver la lista ya puedes adivinar los nombres de algunos mnemónicos válidos (LDX, STX, LDY, STY, INY, DEX y DEY)

Selecciona STA n:n de la lista. El número 141 es insertado, el cursor se mueve a la siguiente celda, y el modo es cambiado de vuelta a EDT MEM.

Prog. (169 65 141 40 2)

Presiona 4, 0 y * para insertar el primer byte del operando (el segmento).

Presiona 2 y selecciona aceptar (OK) para inserar el segundo byte del operando (la página).

Presiona # para cambiar al modo NAV ASM.

Prog. (ASM - LDA/STA)

Aquí está la vista de ensamblador del programa completo:

LDA #65
STA 2:40
BRK

para resumir:

  1. La primera operación carga el acumulador con el valor 65.
  2. La segunda operación almacena el acumulador (65) en la celda 2:40, causando que el carácter A (ver la tabla de arriba) aparezca en la esquina superior izquierda de la pantalla.
  3. El tercer operador detiene el VM.

Selecciona depurar (Debug) para probar el programa.

Debug

Presiona 1 para avanzar un paso. El acumulador ahora contiene 65 y el contador de programa es 3:2.

Presiona 1 para avanzar otro paso. El contador de programa ahora contiene 3:5. Puedes chequear que el carácter A es visible en la pantalla del VM presionando # y volver a la vista de CPU, presionando # de nuevo.

Selecciona abortar (Abort) para terminar el programa y volver al editor.

Save

Al principio, lo más probrable es que escribas programas cortos, y guardar tu progreso no debería ser una proriedad. De hecho, empezar cada vez desde cero te podría ayudar a consolidar lo que aprendiste. Si en el futuro comienzas a escribir programas más grandes, hay una forma de guardarlos:

Selecciona guardar (Save), escribe Tutorial y selecciona aceptar (OK).

Main Menu (Store)

Selecciona atrás (Back) seguido de salir (Exit) para cerrar JBit, y vuelve a abrirlo.

JBit es un sistema modular, y puede ser configurado para incluir o no ciertas herramientas, dependiendo de las limitaciones de tu teléfono. El menú principal muestra la lista de las herramientas incluidas.

En este tutorial estoy usando JBit1M, una versión de JBit diseñada para teléfonos menos modernos, que incluye sólo dos herramientas: almacenamiento (Store) y el editor. Ya hemos usado el editor, y luego veremos como usar el almacenamiento, pero antes, voy a presentar las herramientas que probablemente tenga tu versión de JBit:

Ejemplos (Demos)
Esta herramienta provee algunos programas listos para que puedas estudiarlos. En particular, los ejemplos de 6502 están especialmente escritos para el programador principiante. Si tienes problemas instalando una versión de JBit que incluya los ejemplos, puedes escribirlos a mano usando la hoja de programas JBit-E0.pdf como guía.
Dibujar (Paint)
Esta herramienta te permite crear y editar imágenes simples con JBit. Está diseñado para enseñar como crear tus propias herramientas, y no es muy avanzado, pero lo mismo puedes ser útil.

Una cosa importante que debes comprender es que las herramientas corren en el programa actual. A diferencia de muchas aplicaciones de computadoras, JBit sólo puede trabajar en un archivo a la vez, si ejecutas un ejemplo, o cargas un programa, el programa en el que estabas trabajando va a ser reemplazado sin aviso, aunque no lo hayas guardado.

Te preguntarás para que existe una herramienta de dibujo, si la pantalla del VM no puede mostrar imágenes. La razón es que puedes equipar el VM con diferentes versiones del chip de entrada/salida (IO Chip):

Micro entrada/salida (MicroIO)
El MicroIO solamente provee las funciones más básicas para escribir programas interactivos.
MIDP1
La versión MIDP1 añade varias funcionalidades, principalmente, la capacidad de mostrar imágenes.
MIDP2
La versión MIDP2 añade la capacidad de escribir juegos de acción en dos dimensiones.

La versión MicroIO no debería ser descartada. Puedes aprenderla rápidamentey es tan simple que no necesitas consultar una guía para usarla. Aún si tienes una mejor versión disponible, usar la versión MicroIO es una buena idea.

Selecciona almacenamiento (Store).

Store

La herramienta almacenamiento te provee de un contenedor donde puedes mantener tus programas para accederlos posteriormente. Ya has usado la herramienta almacenamiento sin notarlo, cuando guardaste desde el editor, pero accederlo manualmente te provee de más opciones. Puedes ver la lista de los programas almacenados, y gestionarlos con algunos comandos.

Cargar y editar (Load&Edit, el comando predeterminado) carga un programa y abre el editor. Cargar y correr (Load&Run) carga el programa y corre el VM. Cargar (Load) sólo carga el programa.

guardar (Save) te pide el nombre del programa actual y lo guarda. No puedes sobreescribir programas usando guardar, para ello debes usar sobreescribir (Overwrite).

Información (Info), Copiar (Copy), Renombrar (Rename) y Borrar (Delete) hacen exactamente lo que sus nombres indican. No alteran al programa actual.

Cuando actualizas JBit a una nueva versión, tu teléfono debería preguntarte si quieres mantener tus datos, deberías responder que si, para mantener tus programas guardados. Esto varía de telefono en telefono.

Selecciona Tutorial.

Prog. (162 88 142 40 2)

Aquí tienes una rápida sesión de programación, para repasar:

  1. Presiona 5 para empezar a editar.
  2. Presiona # para buscar el primer opcode.
  3. Teclea 539 para LDX.
  4. Selecciona LDX #n de la lista.
  5. Teclea 88* para ingresar el operador.
  6. Presiona # para buscar el segundo opcode.
  7. Teclea 789 para STX.
  8. Selecciona STX n:n de la lista.
  9. Selecciona aceptar (OK) para confirmar los cambios, (el resultado debería ser: 162 88 142 40 2).
  10. Presiona * para correr el programa.
  11. Selecciona Video para ver la pantalla.
  12. Presiona cualquier tecla para volver a la pantalla de programa detenido.
  13. Selecciona terminar (End) para volver al editor.
  14. Selecciona guardar (Save) para guardar la nueva versión del programa en el almacenamiento.

Selecciona atrás (Back) y salir (Exit) para cerrar JBit.