Added comments and clarification on the PIC and PIT emulation code.
This commit is contained in:
parent
0f6b11c78e
commit
541ce3c478
30
CMOS.js
30
CMOS.js
|
@ -4,22 +4,34 @@
|
|||
Original is Copyright (c) 2011-2012 Fabrice Bellard
|
||||
Redistribution or commercial use is prohibited without the author's permission.
|
||||
|
||||
Clock Emulator
|
||||
CMOS Ram Memory, actually just the RTC Clock Emulator
|
||||
|
||||
Useful references:
|
||||
------------------
|
||||
http://www.bioscentral.com/misc/cmosmap.htm
|
||||
http://wiki.osdev.org/CMOS
|
||||
*/
|
||||
function formatter(a) { return ((a / 10) << 4) | (a % 10);}
|
||||
|
||||
/*
|
||||
In this implementation, bytes are stored in the RTC in BCD format
|
||||
binary -> bcd: bcd = ((bin / 10) << 4) | (bin % 10)
|
||||
bcd -> binary: bin = ((bcd / 16) * 10) + (bcd & 0xf)
|
||||
*/
|
||||
function bin_to_bcd(a) { return ((a / 10) << 4) | (a % 10);}
|
||||
|
||||
function CMOS(PC) {
|
||||
var time_array, d;
|
||||
time_array = new Uint8Array(128);
|
||||
this.cmos_data = time_array;
|
||||
this.cmos_index = 0;
|
||||
d = new Date();
|
||||
time_array[0] = formatter(d.getUTCSeconds());
|
||||
time_array[2] = formatter(d.getUTCMinutes());
|
||||
time_array[4] = formatter(d.getUTCHours());
|
||||
time_array[6] = formatter(d.getUTCDay());
|
||||
time_array[7] = formatter(d.getUTCDate());
|
||||
time_array[8] = formatter(d.getUTCMonth() + 1);
|
||||
time_array[9] = formatter(d.getUTCFullYear() % 100);
|
||||
time_array[0] = bin_to_bcd(d.getUTCSeconds());
|
||||
time_array[2] = bin_to_bcd(d.getUTCMinutes());
|
||||
time_array[4] = bin_to_bcd(d.getUTCHours());
|
||||
time_array[6] = bin_to_bcd(d.getUTCDay());
|
||||
time_array[7] = bin_to_bcd(d.getUTCDate());
|
||||
time_array[8] = bin_to_bcd(d.getUTCMonth() + 1);
|
||||
time_array[9] = bin_to_bcd(d.getUTCFullYear() % 100);
|
||||
time_array[10] = 0x26;
|
||||
time_array[11] = 0x02;
|
||||
time_array[12] = 0x00;
|
||||
|
|
|
@ -7,25 +7,25 @@ Redistribution or commercial use is prohibited without the author's permission.
|
|||
Main PC Emulator Routine
|
||||
*/
|
||||
|
||||
// used as callback wrappers for emulated PIT and PIC chips
|
||||
function set_hard_irq_wrapper(irq) { this.hard_irq = irq;}
|
||||
|
||||
function return_cycle_count() { return this.cycle_count; }
|
||||
|
||||
function PCEmulator(uh) {
|
||||
function PCEmulator(params) {
|
||||
var cpu;
|
||||
cpu = new CPU_X86();
|
||||
this.cpu = cpu;
|
||||
cpu.phys_mem_resize(uh.mem_size);
|
||||
cpu.phys_mem_resize(params.mem_size);
|
||||
this.init_ioports();
|
||||
this.register_ioport_write(0x80, 1, 1, this.ioport80_write);
|
||||
this.pic = new PIC_Controller(this, 0x20, 0xa0, set_hard_irq_wrapper.bind(cpu));
|
||||
this.pit = new PIT(this, this.pic.set_irq.bind(this.pic, 0), return_cycle_count.bind(cpu));
|
||||
this.cmos = new CMOS(this);
|
||||
this.serial = new Serial(this, 0x3f8, this.pic.set_irq.bind(this.pic, 4), uh.serial_write);
|
||||
this.serial = new Serial(this, 0x3f8, this.pic.set_irq.bind(this.pic, 4), params.serial_write);
|
||||
this.kbd = new KBD(this, this.reset.bind(this));
|
||||
this.reset_request = 0;
|
||||
if (uh.clipboard_get && uh.clipboard_set) {
|
||||
this.jsclipboard = new clipboard_device(this, 0x3c0, uh.clipboard_get, uh.clipboard_set, uh.get_boot_time);
|
||||
if (params.clipboard_get && params.clipboard_set) {
|
||||
this.jsclipboard = new clipboard_device(this, 0x3c0, params.clipboard_get, params.clipboard_set, params.get_boot_time);
|
||||
}
|
||||
cpu.ld8_port = this.ld8_port.bind(this);
|
||||
cpu.ld16_port = this.ld16_port.bind(this);
|
||||
|
@ -36,7 +36,7 @@ function PCEmulator(uh) {
|
|||
cpu.get_hard_intno = this.pic.get_hard_intno.bind(this.pic);
|
||||
}
|
||||
|
||||
PCEmulator.prototype.load_binary = function(Gg, ha) { return this.cpu.load_binary(Gg, ha); };
|
||||
PCEmulator.prototype.load_binary = function(url, mem8_loc) { return this.cpu.load_binary(url, mem8_loc); };
|
||||
|
||||
PCEmulator.prototype.start = function() { setTimeout(this.timer_func.bind(this), 10); };
|
||||
|
||||
|
|
212
PIC.js
212
PIC.js
|
@ -4,8 +4,68 @@ JSLinux-deobfuscated - An annotated version of the original JSLinux.
|
|||
Original is Copyright (c) 2011-2012 Fabrice Bellard
|
||||
Redistribution or commercial use is prohibited without the author's permission.
|
||||
|
||||
8259 PIC (Programmable Interrupt Controller) Emulation Code
|
||||
8259A PIC (Programmable Interrupt Controller) Emulation Code
|
||||
|
||||
The 8259 combines multiple interrupt input sources into a single
|
||||
interrupt output to the host microprocessor, extending the interrupt
|
||||
levels available in a system beyond the one or two levels found on the
|
||||
processor chip.
|
||||
|
||||
There are three registers, an Interrupt Mask Register (IMR), an
|
||||
Interrupt Request Register (IRR), and an In-Service Register
|
||||
(ISR):
|
||||
IRR - a mask of the current interrupts that are pending acknowledgement
|
||||
ISR - a mask of the interrupts that are pending an EOI
|
||||
IMR - a mask of interrupts that should not be sent an acknowledgement
|
||||
|
||||
End Of Interrupt (EOI) operations support specific EOI, non-specific
|
||||
EOI, and auto-EOI. A specific EOI specifies the IRQ level it is
|
||||
acknowledging in the ISR. A non-specific EOI resets the IRQ level in
|
||||
the ISR. Auto-EOI resets the IRQ level in the ISR immediately after
|
||||
the interrupt is acknowledged.
|
||||
|
||||
After the IBM XT, it was decided that 8 IRQs was not enough.
|
||||
The backwards-compatible solution was simply to chain two 8259As together,
|
||||
the master and slave PIC.
|
||||
|
||||
Useful References
|
||||
-----------------
|
||||
https://en.wikipedia.org/wiki/Programmable_Interrupt_Controller
|
||||
https://en.wikipedia.org/wiki/Intel_8259
|
||||
http://www.thesatya.com/8259.html
|
||||
*/
|
||||
|
||||
/*
|
||||
Common PC arrangements of IRQ lines:
|
||||
------------------------------------
|
||||
|
||||
PC/AT and later systems had two 8259 controllers, master and
|
||||
slave. IRQ0 through IRQ7 are the master 8259's interrupt lines, while
|
||||
IRQ8 through IRQ15 are the slave 8259's interrupt lines. The labels on
|
||||
the pins on an 8259 are IR0 through IR7. IRQ0 through IRQ15 are the
|
||||
names of the ISA bus's lines to which the 8259s are attached.
|
||||
|
||||
Master 8259
|
||||
IRQ0 – Intel 8253 or Intel 8254 Programmable Interval Timer, aka the system timer
|
||||
IRQ1 – Intel 8042 keyboard controller
|
||||
IRQ2 – not assigned in PC/XT; cascaded to slave 8259 INT line in PC/AT
|
||||
IRQ3 – 8250 UART serial ports 2 and 4
|
||||
IRQ4 – 8250 UART serial ports 1 and 3
|
||||
IRQ5 – hard disk controller in PC/XT; Intel 8255 parallel ports 2 and 3 in PC/AT
|
||||
IRQ6 – Intel 82072A floppy disk controller
|
||||
IRQ7 – Intel 8255 parallel port 1 / spurious interrupt
|
||||
|
||||
Slave 8259 (PC/AT and later only)
|
||||
IRQ8 – real-time clock (RTC)
|
||||
IRQ9 – no common assignment, but 8-bit cards' IRQ2 line is routed to this interrupt.
|
||||
IRQ10 – no common assignment
|
||||
IRQ11 – no common assignment
|
||||
IRQ12 – Intel 8042 PS/2 mouse controller
|
||||
IRQ13 – math coprocessor
|
||||
IRQ14 – hard disk controller 1
|
||||
IRQ15 – hard disk controller 2
|
||||
*/
|
||||
|
||||
function PIC(PC, port_num) {
|
||||
PC.register_ioport_write(port_num, 2, 1, this.ioport_write.bind(this));
|
||||
PC.register_ioport_read(port_num, 2, 1, this.ioport_read.bind(this));
|
||||
|
@ -13,9 +73,9 @@ function PIC(PC, port_num) {
|
|||
}
|
||||
PIC.prototype.reset = function() {
|
||||
this.last_irr = 0;
|
||||
this.irr = 0;
|
||||
this.imr = 0;
|
||||
this.isr = 0;
|
||||
this.irr = 0; //Interrupt Request Register
|
||||
this.imr = 0; //Interrupt Mask Register
|
||||
this.isr = 0; //In-Service Register
|
||||
this.priority_add = 0;
|
||||
this.irq_base = 0;
|
||||
this.read_reg_select = 0;
|
||||
|
@ -24,54 +84,66 @@ PIC.prototype.reset = function() {
|
|||
this.auto_eoi = 0;
|
||||
this.rotate_on_autoeoi = 0;
|
||||
this.init4 = 0;
|
||||
this.elcr = 0;
|
||||
this.elcr = 0; // Edge/Level Control Register
|
||||
this.elcr_mask = 0;
|
||||
};
|
||||
PIC.prototype.set_irq1 = function(Rg, Qf) {
|
||||
var wc;
|
||||
wc = 1 << Rg;
|
||||
PIC.prototype.set_irq1 = function(irq, Qf) {
|
||||
var ir_register;
|
||||
ir_register = 1 << irq;
|
||||
if (Qf) {
|
||||
if ((this.last_irr & wc) == 0)
|
||||
this.irr |= wc;
|
||||
this.last_irr |= wc;
|
||||
if ((this.last_irr & ir_register) == 0)
|
||||
this.irr |= ir_register;
|
||||
this.last_irr |= ir_register;
|
||||
} else {
|
||||
this.last_irr &= ~wc;
|
||||
this.last_irr &= ~ir_register;
|
||||
}
|
||||
};
|
||||
PIC.prototype.get_priority = function(wc) {
|
||||
var Sg;
|
||||
if (wc == 0)
|
||||
/*
|
||||
The priority assignments for IRQ0-7 seem to be maintained in a
|
||||
cyclic order modulo 8 by the 8259A. On bootup, it default to:
|
||||
|
||||
Priority: 0 1 2 3 4 5 6 7
|
||||
IRQ: 7 6 5 4 3 2 1 0
|
||||
|
||||
but can be rotated automatically or programmatically to a state e.g.:
|
||||
|
||||
Priority: 5 6 7 0 1 2 3 4
|
||||
IRQ: 7 6 5 4 3 2 1 0
|
||||
*/
|
||||
PIC.prototype.get_priority = function(ir_register) {
|
||||
var priority;
|
||||
if (ir_register == 0)
|
||||
return -1;
|
||||
Sg = 7;
|
||||
while ((wc & (1 << ((Sg + this.priority_add) & 7))) == 0)
|
||||
Sg--;
|
||||
return Sg;
|
||||
priority = 7;
|
||||
while ((ir_register & (1 << ((priority + this.priority_add) & 7))) == 0)
|
||||
priority--;
|
||||
return priority;
|
||||
};
|
||||
PIC.prototype.get_irq = function() {
|
||||
var wc, Tg, Sg;
|
||||
wc = this.irr & ~this.imr;
|
||||
Sg = this.get_priority(wc);
|
||||
if (Sg < 0)
|
||||
var ir_register, in_service_priority, priority;
|
||||
ir_register = this.irr & ~this.imr;
|
||||
priority = this.get_priority(ir_register);
|
||||
if (priority < 0)
|
||||
return -1;
|
||||
Tg = this.get_priority(this.isr);
|
||||
if (Sg > Tg) {
|
||||
return Sg;
|
||||
in_service_priority = this.get_priority(this.isr);
|
||||
if (priority > in_service_priority) {
|
||||
return priority;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
PIC.prototype.intack = function(Rg) {
|
||||
PIC.prototype.intack = function(irq) {
|
||||
if (this.auto_eoi) {
|
||||
if (this.rotate_on_auto_eoi)
|
||||
this.priority_add = (Rg + 1) & 7;
|
||||
this.priority_add = (irq + 1) & 7;
|
||||
} else {
|
||||
this.isr |= (1 << Rg);
|
||||
this.isr |= (1 << irq);
|
||||
}
|
||||
if (!(this.elcr & (1 << Rg)))
|
||||
this.irr &= ~(1 << Rg);
|
||||
if (!(this.elcr & (1 << irq)))
|
||||
this.irr &= ~(1 << irq);
|
||||
};
|
||||
PIC.prototype.ioport_write = function(mem8_loc, x) {
|
||||
var Sg;
|
||||
var priority;
|
||||
mem8_loc &= 1;
|
||||
if (mem8_loc == 0) {
|
||||
if (x & 0x10) {
|
||||
|
@ -105,9 +177,9 @@ PIC.prototype.ioport_write = function(mem8_loc, x) {
|
|||
break;
|
||||
case 0x20:
|
||||
case 0xa0:
|
||||
Sg = this.get_priority(this.isr);
|
||||
if (Sg >= 0) {
|
||||
this.isr &= ~(1 << ((Sg + this.priority_add) & 7));
|
||||
priority = this.get_priority(this.isr);
|
||||
if (priority >= 0) {
|
||||
this.isr &= ~(1 << ((priority + this.priority_add) & 7));
|
||||
}
|
||||
if (x == 0xa0)
|
||||
this.priority_add = (this.priority_add + 1) & 7;
|
||||
|
@ -120,8 +192,8 @@ PIC.prototype.ioport_write = function(mem8_loc, x) {
|
|||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
Sg = x & 7;
|
||||
this.isr &= ~(1 << Sg);
|
||||
priority = x & 7;
|
||||
this.isr &= ~(1 << priority);
|
||||
break;
|
||||
case 0xc0:
|
||||
case 0xc1:
|
||||
|
@ -141,9 +213,9 @@ PIC.prototype.ioport_write = function(mem8_loc, x) {
|
|||
case 0xe5:
|
||||
case 0xe6:
|
||||
case 0xe7:
|
||||
Sg = x & 7;
|
||||
this.isr &= ~(1 << Sg);
|
||||
this.priority_add = (Sg + 1) & 7;
|
||||
priority = x & 7;
|
||||
this.isr &= ~(1 << priority);
|
||||
this.priority_add = (priority + 1) & 7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -172,69 +244,69 @@ PIC.prototype.ioport_write = function(mem8_loc, x) {
|
|||
}
|
||||
};
|
||||
PIC.prototype.ioport_read = function(Ug) {
|
||||
var mem8_loc, Pg;
|
||||
var mem8_loc, return_register;
|
||||
mem8_loc = Ug & 1;
|
||||
if (mem8_loc == 0) {
|
||||
if (this.read_reg_select)
|
||||
Pg = this.isr;
|
||||
return_register = this.isr;
|
||||
else
|
||||
Pg = this.irr;
|
||||
return_register = this.irr;
|
||||
} else {
|
||||
Pg = this.imr;
|
||||
return_register = this.imr;
|
||||
}
|
||||
return Pg;
|
||||
return return_register;
|
||||
};
|
||||
|
||||
|
||||
function PIC_Controller(PC, Wg, Ug, Xg) {
|
||||
function PIC_Controller(PC, master_PIC_port, slave_PIC_port, cpu_set_irq_callback) {
|
||||
this.pics = new Array();
|
||||
this.pics[0] = new PIC(PC, Wg);
|
||||
this.pics[1] = new PIC(PC, Ug);
|
||||
this.pics[0] = new PIC(PC, master_PIC_port);
|
||||
this.pics[1] = new PIC(PC, slave_PIC_port);
|
||||
this.pics[0].elcr_mask = 0xf8;
|
||||
this.pics[1].elcr_mask = 0xde;
|
||||
this.irq_requested = 0;
|
||||
this.cpu_set_irq = Xg;
|
||||
this.cpu_set_irq = cpu_set_irq_callback;
|
||||
this.pics[0].update_irq = this.update_irq.bind(this);
|
||||
this.pics[1].update_irq = this.update_irq.bind(this);
|
||||
}
|
||||
PIC_Controller.prototype.update_irq = function() {
|
||||
var Yg, Rg;
|
||||
Yg = this.pics[1].get_irq();
|
||||
if (Yg >= 0) {
|
||||
var slave_irq, irq;
|
||||
slave_irq = this.pics[1].get_irq();
|
||||
if (slave_irq >= 0) {
|
||||
this.pics[0].set_irq1(2, 1);
|
||||
this.pics[0].set_irq1(2, 0);
|
||||
}
|
||||
Rg = this.pics[0].get_irq();
|
||||
if (Rg >= 0) {
|
||||
irq = this.pics[0].get_irq();
|
||||
if (irq >= 0) {
|
||||
this.cpu_set_irq(1);
|
||||
} else {
|
||||
this.cpu_set_irq(0);
|
||||
}
|
||||
};
|
||||
PIC_Controller.prototype.set_irq = function(Rg, Qf) {
|
||||
this.pics[Rg >> 3].set_irq1(Rg & 7, Qf);
|
||||
PIC_Controller.prototype.set_irq = function(irq, Qf) {
|
||||
this.pics[irq >> 3].set_irq1(irq & 7, Qf);
|
||||
this.update_irq();
|
||||
};
|
||||
PIC_Controller.prototype.get_hard_intno = function() {
|
||||
var Rg, Yg, intno;
|
||||
Rg = this.pics[0].get_irq();
|
||||
if (Rg >= 0) {
|
||||
this.pics[0].intack(Rg);
|
||||
if (Rg == 2) {
|
||||
Yg = this.pics[1].get_irq();
|
||||
if (Yg >= 0) {
|
||||
this.pics[1].intack(Yg);
|
||||
var irq, slave_irq, intno;
|
||||
irq = this.pics[0].get_irq();
|
||||
if (irq >= 0) {
|
||||
this.pics[0].intack(irq);
|
||||
if (irq == 2) { //IRQ 2 cascaded to slave 8259 INT line in PC/AT
|
||||
slave_irq = this.pics[1].get_irq();
|
||||
if (slave_irq >= 0) {
|
||||
this.pics[1].intack(slave_irq);
|
||||
} else {
|
||||
Yg = 7;
|
||||
slave_irq = 7;
|
||||
}
|
||||
intno = this.pics[1].irq_base + Yg;
|
||||
Rg = Yg + 8;
|
||||
intno = this.pics[1].irq_base + slave_irq;
|
||||
irq = slave_irq + 8;
|
||||
} else {
|
||||
intno = this.pics[0].irq_base + Rg;
|
||||
intno = this.pics[0].irq_base + irq;
|
||||
}
|
||||
} else {
|
||||
Rg = 7;
|
||||
intno = this.pics[0].irq_base + Rg;
|
||||
irq = 7;
|
||||
intno = this.pics[0].irq_base + irq;
|
||||
}
|
||||
this.update_irq();
|
||||
return intno;
|
||||
|
|
46
PIT.js
46
PIT.js
|
@ -5,19 +5,23 @@ Original is Copyright (c) 2011-2012 Fabrice Bellard
|
|||
Redistribution or commercial use is prohibited without the author's permission.
|
||||
|
||||
8254 Programmble Interrupt Timer Emulator
|
||||
|
||||
Useful References
|
||||
-----------------
|
||||
https://en.wikipedia.org/wiki/Intel_8253
|
||||
*/
|
||||
function PIT(PC, ah, bh) {
|
||||
function PIT(PC, set_irq_callback, cycle_count_callback) {
|
||||
var s, i;
|
||||
this.pit_channels = new Array();
|
||||
for (i = 0; i < 3; i++) {
|
||||
s = new IRQCH(bh);
|
||||
s = new IRQCH(cycle_count_callback);
|
||||
this.pit_channels[i] = s;
|
||||
s.mode = 3;
|
||||
s.gate = (i != 2) >> 0;
|
||||
s.pit_load_count(0);
|
||||
}
|
||||
this.speaker_data_on = 0;
|
||||
this.set_irq = ah;
|
||||
this.set_irq = set_irq_callback;
|
||||
// Ports:
|
||||
// 0x40: Channel 0 data port
|
||||
// 0x61: Control
|
||||
|
@ -27,9 +31,7 @@ function PIT(PC, ah, bh) {
|
|||
PC.register_ioport_write(0x61, 1, 1, this.speaker_ioport_write.bind(this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
function IRQCH(bh) {
|
||||
function IRQCH(cycle_count_callback) {
|
||||
this.count = 0;
|
||||
this.latched_count = 0;
|
||||
this.rw_state = 0;
|
||||
|
@ -37,7 +39,7 @@ function IRQCH(bh) {
|
|||
this.bcd = 0;
|
||||
this.gate = 0;
|
||||
this.count_load_time = 0;
|
||||
this.get_ticks = bh;
|
||||
this.get_ticks = cycle_count_callback;
|
||||
this.pit_time_unit = 1193182 / 2000000;
|
||||
}
|
||||
IRQCH.prototype.get_time = function() {
|
||||
|
@ -64,29 +66,23 @@ IRQCH.prototype.pit_get_out = function() {
|
|||
d = this.get_time() - this.count_load_time;
|
||||
switch (this.mode) {
|
||||
default:
|
||||
// Interrupt on terminal count
|
||||
case 0:
|
||||
case 0: // Interrupt on terminal count
|
||||
eh = (d >= this.count) >> 0;
|
||||
break;
|
||||
// One shot
|
||||
case 1:
|
||||
case 1: // One shot
|
||||
eh = (d < this.count) >> 0;
|
||||
break;
|
||||
// Frequency divider
|
||||
case 2:
|
||||
case 2: // Frequency divider
|
||||
if ((d % this.count) == 0 && d != 0)
|
||||
eh = 1;
|
||||
else
|
||||
eh = 0;
|
||||
break;
|
||||
// Square wave
|
||||
case 3:
|
||||
case 3: // Square wave
|
||||
eh = ((d % this.count) < (this.count >> 1)) >> 0;
|
||||
break;
|
||||
// SW strobe
|
||||
case 4:
|
||||
// HW strobe
|
||||
case 5:
|
||||
case 4: // SW strobe
|
||||
case 5: // HW strobe
|
||||
eh = (d == this.count) >> 0;
|
||||
break;
|
||||
}
|
||||
|
@ -97,21 +93,21 @@ IRQCH.prototype.get_next_transition_time = function() {
|
|||
d = this.get_time() - this.count_load_time;
|
||||
switch (this.mode) {
|
||||
default:
|
||||
case 0:
|
||||
case 1:
|
||||
case 0: // Interrupt on terminal count
|
||||
case 1: // One shot
|
||||
if (d < this.count)
|
||||
fh = this.count;
|
||||
else
|
||||
return -1;
|
||||
break;
|
||||
case 2:
|
||||
case 2: // Frequency divider
|
||||
base = (d / this.count) * this.count;
|
||||
if ((d - base) == 0 && d != 0)
|
||||
fh = base + this.count;
|
||||
else
|
||||
fh = base + this.count + 1;
|
||||
break;
|
||||
case 3:
|
||||
case 3: // Square wave
|
||||
base = (d / this.count) * this.count;
|
||||
gh = ((this.count + 1) >> 1);
|
||||
if ((d - base) < gh)
|
||||
|
@ -119,8 +115,8 @@ IRQCH.prototype.get_next_transition_time = function() {
|
|||
else
|
||||
fh = base + this.count;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 4: // SW strobe
|
||||
case 5: // HW strobe
|
||||
if (d < this.count)
|
||||
fh = this.count;
|
||||
else if (d == this.count)
|
||||
|
|
Loading…
Reference in New Issue