/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016–2017, 2019–2023 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package java.lang;
public final class MalikInterrupt extends Object
{
private static final int TABLE_ADDRESS = 0x00800000;
private static short[] BUSY;
public static void invoke(int number) throws Throwable {
int error;
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
}
if(number <= 0x22)
{
throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
}
error = 0;
synchronized(BUSY)
{
label0:
{
Object handler;
if((handler = getHandler(number)) == null)
{
error = 1;
break label0;
}
if(!(handler instanceof InterruptVoid) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptVoid;"), 0))
{
error = 2;
break label0;
}
BUSY[number]++;
}
}
switch(error)
{
case 1:
throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
case 2:
throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptVoid.");
}
try
{
MalikSystem.interrupt(number);
}
finally
{
exit(number);
}
}
public static void invoke(int number, int argument) throws Throwable {
int error;
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
}
if(number <= 0x22)
{
throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
}
error = 0;
synchronized(BUSY)
{
label0:
{
Object handler;
if((handler = getHandler(number)) == null)
{
error = 1;
break label0;
}
if(!(handler instanceof InterruptInt) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptInt;"), 0))
{
error = 2;
break label0;
}
BUSY[number]++;
}
}
switch(error)
{
case 1:
throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
case 2:
throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptInt.");
}
try
{
MalikSystem.interrupt(argument, number);
}
finally
{
exit(number);
}
}
public static void invoke(int number, long argument) throws Throwable {
int error;
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
}
if(number <= 0x22)
{
throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
}
error = 0;
synchronized(BUSY)
{
label0:
{
Object handler;
if((handler = getHandler(number)) == null)
{
error = 1;
break label0;
}
if(!(handler instanceof InterruptLong) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptLong;"), 0))
{
error = 2;
break label0;
}
BUSY[number]++;
}
}
switch(error)
{
case 1:
throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
case 2:
throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptLong.");
}
try
{
MalikSystem.interrupt(argument, number);
}
finally
{
exit(number);
}
}
public static void invoke(int number, Object argument) throws Throwable {
int error;
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.invoke: аргумент number выходит из диапазона.");
}
if(number <= 0x22)
{
throw new SecurityException("MalikInterrupt.invoke: невозможно вызвать системный обработчик прерывания.");
}
error = 0;
synchronized(BUSY)
{
label0:
{
Object handler;
if((handler = getHandler(number)) == null)
{
error = 1;
break label0;
}
if(!(handler instanceof InterruptObject) || getEntry(number) != handler.getClass().getInterfaceMethodEntryPoint(MalikSystem.getClassInstance("Ljava/lang/InterruptObject;"), 0))
{
error = 2;
break label0;
}
BUSY[number]++;
}
}
switch(error)
{
case 1:
throw new NullPointerException("MalikInterrupt.invoke: обработчик прерывания не задан.");
case 2:
throw new ClassCastException("MalikInterrupt.invoke: обработчик прерывания не задан как InterruptObject.");
}
try
{
MalikSystem.interrupt(argument, number);
}
finally
{
exit(number);
}
}
public static void register(int number, InterruptVoid handler) {
init();
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
}
if(number <= 0x22 && getHandler(number) != null)
{
throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
}
if(number <= 0x22)
{
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptVoid;"));
return;
}
synchronized(BUSY)
{
while(BUSY[number] != 0)
{
try
{
BUSY.wait();
}
catch(InterruptedException e)
{
e.printRealStackTrace();
}
}
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptVoid;"));
}
}
public static void register(int number, InterruptInt handler) {
init();
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
}
if(number <= 0x22 && getHandler(number) != null)
{
throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
}
if(number <= 0x22)
{
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptInt;"));
return;
}
synchronized(BUSY)
{
while(BUSY[number] != 0)
{
try
{
BUSY.wait();
}
catch(InterruptedException e)
{
e.printRealStackTrace();
}
}
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptInt;"));
}
}
public static void register(int number, InterruptLong handler) {
init();
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
}
if(number <= 0x22 && getHandler(number) != null)
{
throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
}
if(number <= 0x22)
{
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptLong;"));
return;
}
synchronized(BUSY)
{
while(BUSY[number] != 0)
{
try
{
BUSY.wait();
}
catch(InterruptedException e)
{
e.printRealStackTrace();
}
}
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptLong;"));
}
}
public static void register(int number, InterruptObject handler) {
init();
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.register: аргумент number выходит из диапазона.");
}
if(number <= 0x22 && getHandler(number) != null)
{
throw new SecurityException("MalikInterrupt.register: невозможно переписать системный обработчик прерывания.");
}
if(number <= 0x22)
{
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptObject;"));
return;
}
synchronized(BUSY)
{
while(BUSY[number] != 0)
{
try
{
BUSY.wait();
}
catch(InterruptedException e)
{
e.printRealStackTrace();
}
}
register(number, handler, MalikSystem.getClassInstance("Ljava/lang/InterruptObject;"));
}
}
public static void remove(int number) {
init();
if(number < 0x00 || number > 0xff)
{
throw new IllegalArgumentException("MalikInterrupt.remove: аргумент number выходит из диапазона.");
}
if(number <= 0x22 && getHandler(number) != null)
{
throw new SecurityException("MalikInterrupt.remove: невозможно переписать системный обработчик прерывания.");
}
if(number <= 0x22)
{
register(number, null, null);
return;
}
synchronized(BUSY)
{
while(BUSY[number] != 0)
{
try
{
BUSY.wait();
}
catch(InterruptedException e)
{
e.printRealStackTrace();
}
}
register(number, null, null);
}
}
public static void enable(boolean enabled) {
try
{
MalikSystem.interrupt(enabled ? 1 : 0, 0x22);
}
catch(Throwable e)
{
}
}
public static void enable() {
try
{
MalikSystem.interrupt(1, 0x22);
}
catch(Throwable e)
{
}
}
public static void disable() {
try
{
MalikSystem.interrupt(0, 0x22);
}
catch(Throwable e)
{
}
}
public static boolean enabled() {
boolean result = false;
try
{
MalikSystem.interrupt(MalikSystem.getLocalVariableAddress(result), 0x21);
}
catch(Throwable t)
{
}
return result;
}
private static void init() {
if(BUSY == null) BUSY = new short[0x0100];
}
private static void exit(int number) {
synchronized(BUSY)
{
if(--BUSY[number] == 0) BUSY.notifyAll();
}
}
private static void register(int number, Object handler, Class type) {
int entry = handler != null ? handler.getClass().getInterfaceMethodEntryPoint(type, 0) : 0;
int address = TABLE_ADDRESS + (number << 3);
MalikSystem.setIntAt(address, 0);
if(entry == 0)
{
MalikSystem.setObjectAt(address + 4, null);
return;
}
MalikSystem.setObjectAt(address + 4, handler);
MalikSystem.setIntAt(address, entry);
}
private static int getEntry(int number) {
return MalikSystem.getIntAt(TABLE_ADDRESS + (number << 3));
}
private static Object getHandler(int number) {
return MalikSystem.getObjectAt((TABLE_ADDRESS + 4) + (number << 3));
}
private MalikInterrupt() {
}
}