Hi folks,
A bunch of generous and smart people have managed to figure out how to control the LEDs on the Acer EasyStore H340 in Linux. To read more on this, please go here.
As a courtesy, I am hosting the current and possibly future code for leds-h340-0.2. Current version is 0.2. This is done with permission from the author Alexander Georg. I hope you’ll find this as useful as I do. It turns off the blinking “i” LED which was driving me nuts.
Usage (taken from the post above):
tar xzvf h340-leds-0.2.tar.gz
make
sudo insmod leds-h340.ko
Disable the blinking “i” with:
echo 0 > /sys/class/leds/h340:InfoLedBlue/brightness
echo 255 > /sys/class/leds/h340:InfoLedBlue/brightness
Turn the “i” red:
echo 0 > /sys/class/leds/h340:InfoLedRed/brightness
leds-h340-0.2.tar.gz
I haven’t posted in a little while but you should expect to see some reviews of the new Core i7 MacBook Pro, iPad and Acer 1810TZ laptop. Just gonna get set time to sit down and write my personal impressions on the subject.
Will also post how well Ubuntu 9.10 (Karmic Koala) works on the Acer 1810TZ right out of the box. Quite impressive. More on that later.
Once upon a time, way back, I mean, way way back in 1998, me and my brother decided to see if we could cover a Pet Shop Boys song we really liked called “Left to my own devices.” Intent was to have a song done for a PSB tribute album that never really came to fruition (I think).
Anyway, since I didn’t have any musical abilities (instrument wise), my brother did the music and I did some vocals with an extremely el-cheapo PC mike. Well, I am not proud of my singing, but here it is. You can laugh at it if you prefer, I won’t mind. :)
Farhan Yousaf and Adnan Yousaf – Left to my own devices
I wonder though if my voice has changed since. I was in my early 20’s then, and now in my early 30’s… Oh, and I will be posting more of the crazy stuff I was into when I had the mental capacity and the oodles of time needed to play with whatever I had access to that day. I don’t think there are any real but serious followers of this blog, so this serves as sort of a personal diary.
In the heydays of the mid-to-late 80’s, I had an Atari 800 XL. And considering that I spent most of my young adolescent days on it, I still have very fond memories of it.
When software emulators of the Atari came out, I wanted to know how it was done. Thinking more about how the CPU and the supporting sound and graphic chipsets gave me a geeky urge to write an emulator for the CPU used by those generation of 8-bit machines. The CPU used was the 6502. So folks, while this work is in progress, I wrote a very basic skeleton of an emulator written completely in Ruby. It does not very much, but I figure if anyone wanted to take a look at bad and unoptimized coding, I shouldn’t give them a reason to look elsewhere.
Download 6502.rb.bz2
Download test binary – displays alphabets from A to Z
#!/usr/bin/ruby
#Written by Farhan Yousaf - March 2010
class CPU6502
attr_accessor :cpu_instance, :cpus, :imagesize, :debug
def initialize
@debug = false
@ip = 0
@imagesize = 0
@pc = 0
@pc_off = 0
@ram = [ ] * 65536
@register = { :A => 0, :X => 0, :Y => 0, :SP => 0xFF, :SR => 0 }
@cpu_instance = 1
@cpus = @cpus.to_i+1
@inst = Array.new
@inst.push [ 0xA2, :immediate, 2, "LDX" ]
@inst.push [ 0xA9, :immediate, 2, "LDA" ]
@inst.push [ 0xA6, :zeropage, 2, "LDX" ]
@inst.push [ 0xB6, :zeropagey, 2, "LDX" ]
@inst.push [ 0xAE, :absolute, 2, "LDX" ]
@inst.push [ 0xBE, :absolutey, 2, "LDX" ]
@inst.push [ 0x8A, :implied, 1, "TXA" ]
@inst.push [ 0x20, :absolute, 3, "JSR" ]
@inst.push [ 0xE8, :absolute, 1, "INX" ]
@inst.push [ 0xE0, :absolute, 2, "CPX" ]
@inst.push [ 0xD0, :absolute, 2, "BNE" ]
@inst.push [ 0x00, :absolute, 2, "BRK" ]
@flag = { :S => 0, :V => 0, :B => 0, :D => 0, :I => 0, :Z =>0, :C => 0 }
@operand=Array.new(2)
end
def display_status
if (@debug)
#printf("PC=%04x SP=%04x A=%02x X=%02x Y=%02x S=%02x C=%d Z=%d\n\n", @pc,@register[:SP],@register[:A],@register[:X],@register[:Y],@flag[:S],@flag[:C]?1:0,@flag[:Z])
end
end
def push(oper1)
#display_status
@ram[@register[:SP]+0x100] = oper1
@register[:SP]-=1
end
def pull
@register[:SP]+=1
@ram[@register[:SP]+0x100]
end
def set_sign(accumulator)
@flag[:S] = accumulator & 0x80 #bit 7 of A
end
def set_zero(accumulator)
# @flag[:Z] = (accumulator==0) ? false:true
if accumulator == 0
@flag[:Z] = 0
else
@flag[:Z] = 1
end
end
def set_carry(accumulator)
@flag[:C] = accumulator
end
def loadi(filen)
@prog = File.open(filen, "rb") { |io| io.read }
@imagesize = @prog.size
end
def runop(opcode, oper1, oper2)
# display_status
case opcode
when 0xA2 #LDX
@register[:X] = oper1
@pc+=2
set_sign(@register[:X])
set_zero(@register[:X])
when 0x8A #TXA
@register[:A] = @register[:X]
@pc+=1
when 0x20 #JSR
@pc = @pc + 3 - 1 #was +3
push((@pc >> 8) & 0xff)
push(@pc & 0xff)
tmp_addr = (oper1 << 8) | oper2
if tmp_addr == 0xFFEE
putc(@register[:A])
@pc = tmp_addr
else
@pc = tmp_addr
end
display_status
@pc = pull
@pc |= (pull << 8) @pc=@pc+1 when 0xE8 #INX @register[:X] = (@register[:X]+1) & 0xff set_sign(@register[:X]) set_zero(@register[:X]) @pc+=1 when 0xE0 #CPX tmp = @register[:X] - oper1 set_carry(@register[:X] >= oper1) #was < 0x100 set_sign(tmp) if (tmp == 0) set_zero(1) else set_zero(0) end @pc+=2 when 0xD0 #BNE display_status @pc+=1 if (@flag[:Z] == 0) if (oper1 > 0x7F)
@pc = @pc - (~(oper1) & 0x00FF)
else
@pc = @pc + (oper1 & 0x00FF)
end
else
@pc=@pc+1
end
when 0xA9 #LDA
set_sign(oper1)
set_zero(oper1)
@register[:A] = oper1
@pc+=2
when 00 #BRK
#puts "************** IN BREAK **************"
@pc+1
exit 0
end
display_status
end
def readmem(pc)
@prog[pc]
end
def decode
@pc=0
while @pc <= (@pc_off + @prog.size)
#puts "inside decode loop - #{@pc} #{@prog.size}"
opcode=readmem(@pc)
@inst.find do |opc,mode,bytes,desc|
if opc == opcode
case bytes
when 2
@operand[0] = readmem(@pc+1)
printf("%04X\t%s #%02X\t\t # %02X%02X -- (%d)\n", @pc,desc, @operand[0], opc, @operand[0], bytes) if @debug
runop(opcode, @operand[0], @operand[1])
when 1
printf("%04X\t%s \t\t #%02X -- (%d)\n", @pc,desc, opc, bytes) if @debug
runop(opcode, @operand[0], @operand[1])
when 3
@operand[0] = readmem(@pc+2)
@operand[1] = readmem(@pc+1)
printf("%04X\t%s $%02X%02X\t\t # %02X%02X%02X -- (%d)\n", @pc,desc, @operand[0], @operand[1], opc, @operand[0],@operand[1], bytes) if @debug
runop(opcode, @operand[0], @operand[1])
end
end
end
end
end
end
if ARGV.empty?
puts "Usage: 6502.rb [image] -d | disassemble"
puts " 6502.rb [image] -r | run"
exit 0
end
myCPU = CPU6502.new
myCPU.loadi(ARGV[0])
myCPU.debug = true if ARGV.find { |a| a == "-d" }
printf("Image length: %d\n", myCPU.imagesize)
myCPU.decode if ARGV.find { |a| a == "-r" }
Comments welcome, but please be gentle. :)
I hope that all my friends and family will have a better new year than 2009. So here’s to 2010!
So I bought this nifty little Intel Atom based NAS-like device. The only problem is that it runs Windows Home Server out of the box and contains no easy way of installing a simple Linux based distribution to get things like ZFS (or ZFS-FUSE) or Linux software RAID working. Well, you can do it by installing Ubuntu on it on another computer and then making a few tweaks and then transplanting the hard disk back into this little machine. I tried, it works, but is slightly time consuming. My experience was that after Ubuntu wouldn’t run any daemons on startup so I spent a good hour trying to understand what the heck was going on. After almost giving up, I blindly typed in my username and password and then ran the SSH daemon (e.g. /etc/init.d/sshd start). Voila! That worked so I could at least get into it and can actually fix things. So to remedy whatever bizarreness was going on, I installed rcconf and disabled and re-enabled all the required daemons and everything was now fine even after a reboot. So that was that.
Next up was the another annoying aspect and limitation of this box. It had only 4 drive bays. Since I didn’t want to waste a whole drive bay on an installation of a rather simple installation of Ubuntu, I wanted to see if I can substitute a USB stick with all the necessary packages and utilize all 4 bays for storage. Well, disaster struck here again. The machine only booted from USB if there were no HDs in the bays or a reset switch was pressed at the back. But how do you permanently change boot priority on a machine that had no video output? The answer to this is that you could build or purchase a cable that hooked on to a 26 pin connector on the motherboard. Slight annoyance here was that building a cable wasn’t exactly easy nor cheap for that matter. An enterprising individual sells pre-made cables for around $100 or so dollars since that option seemed more reasonable than purchasing a crimp tool, and all other necessary parts to build a cable, I decided to go ahead and bite the bullet, i.e. I placed a purchase order.
Another option was to purchase a PCIe X1/X4 video card since the machine had a PCIe slot, but this, again, was not a very tenable option. These cards are almost impossible to find locally and not cheap either. There was also no guarantee that the card would actually function. The option to purchase a pre-made cable looked much better at this point.
Anyhow, I knew about these limitations before I bought the box so I shouldn’t really complain all that much. All this annoyance gave me an idea of building a Linux distribution that contained everything I needed:
- Apache
- HellaNZB or SABNZBd (for News Groups)
- Transmission BitTorrent Client
- FTP Server (I don’t really need this but nice to have)
- Apple File Protocol or netatalk
Now, I am aware that FreeNAS has a lot of that functionality, but is FreeBSD based and not all that updated. So let me know if you’d be interested in willing to help test such a simple Linux based distribution that booted off of a USB stick. Let’s see how far I get with this.
My ideas thus far:
- Use Arch Linux
- Use larch to build a live/USB bootable disk
- Some sort of a basic PHP based user interface to add/remove packages and do configuration
- Email notification of disk full scenarios and/or other hardware issues
- ZFS support through ZFS-FUSE
- Software RAID0/5/etc.
Finally got my transparent bridge up and running. It’s sole purpose in life is to provide QoS (Quality of Service) based prioritization of my VoIP traffic. An added bonus is to provide a snappier web surfing experience if there is other traffic running in the background. All this is being done using the very excellent pfSense. It rocks!
If you want to set one up as well, go here. But to read up more on it, refer to this excellent article.
For those that read underground computer magazines, especially the coded ones, here’s a tool to exact some of the goodies contained with in the .EXEs and .DATs.
You can download here: aftx.pl
Here’s a short script in Perl that checks which users have not logged in over 5 days. I wrote it to run automatically via cron and send emails to users reminding them that their inactivity paste 5 days (for example) will cause their account to be locked and then deleted (e.g. past 10 days). Hope someone finds it useful:
#!/usr/bin/perl
$wtmpx_file_loc = "/var/log/wtmp";
@type=("Empty","Run Lvl","Boot","New Time","Old Time","Init","Login","Normal","Term","Account");
$templ = "l";
$template = "i i A32 A4 A32 A256 i i i2 l4 A20";
# 1 2 3 4 5 6 7 8 9 10 11
$recordsize = length(pack($template,( )));
$records = length(pack($templ,( )));
open(WTMP,$wtmpx_file_loc) or die "Unable to open wtmpx: $!\n";
@users = `egrep -i 'bash' /etc/passwd|awk -F":" '{print \$1}'`;
chomp(@users);
my %user = (
$id => { $lastlog => '' }
);
while (read(WTMP,$record,$recordsize)) {
($ut_type,$ut_pid,$ut_line,$ut_id,$ut_user,$ut_host,$ut_exit,$ut_session,$ut_tv,$ut_addr_v6,$ut_unused)=unpack($template,$record);
if ($ut_user eq "") { next; }
if ($ut_tv > $user{$ut_user}{$lastlog}) {
$user{$ut_user}{$lastlog} = $ut_tv;
}
# print "ut_user=$ut_user ut_host=$ut_host ut_tv=$ut_tv"."\n";
}
#$user{'hfarrell'}{$lastlog} = time() - 24*60*60*5;
$today = time();
foreach $key (@users) {
$diff = $today - $user{$key}{$lastlog};
printf "%-15s - %-25s", $key, scalar localtime($user{$key}{$lastlog});
$days = time() - $user{$key}{$lastlog};
my ($sec, $min, $hour, $day,$month,$year) = (localtime($diff))[0,1,2,3,4,5,6];
if (!defined $user{$key}{$lastlog}) {
print " ** NEVER LOGGED ON";
} elsif ($days > (5*(24*60*60))) {
printf " ** DID NOT LOG IN THE LAST 5 DAYS--OVER BY %d DAY(S)", ($days/(24*60*60));
}
print "\n";
}
// SevenSegment Multiplexing by Farhan Yousaf <farhany AT me DOT com>
// Use freely.
//
void setup() // run once, when the sketch starts
{
for (int i=1; i < 13; i++) {
pinMode(i, OUTPUT);
}
}
byte digits[10][7] = {
// a, b, c, d, e, f, g
{ 1, 1, 1, 1, 1, 1, 0 }, //0
{ 0, 1, 1, 0, 0, 0, 0 }, //1
{ 1, 1, 0, 1, 1, 0, 1 }, //2
{ 1, 1, 1, 1, 0, 0, 1 }, //3
{ 0, 1, 1, 0, 0, 1, 1 }, //4
{ 1, 0, 1, 1, 0, 1, 1 }, //5
{ 1, 0, 1, 1, 1, 1, 1 }, //6
{ 1, 1, 1, 0, 0, 0, 0 }, //7
{ 1, 1, 1, 1, 1, 1, 1 }, //8
{ 1, 1, 1, 1, 0, 1, 1 } //9
};
class SevenSegment {
public:
int _digit;
int _startpin;
int mode; //cathode or anode
void display(int digit);
void setPins(int start_pin);
void clearDisplay();
SevenSegment(int start_pin);
void selectLED(int pin);
};
SevenSegment::SevenSegment(int start_pin) {
setPins(start_pin);
}
void SevenSegment::setPins(int start_pin) {
for (int i=start_pin; i < (start_pin+7); i++) {
pinMode(i, OUTPUT);
}
_startpin=start_pin;
}
void SevenSegment::clearDisplay() {
for (int i=0; i < 7; i++) {
digitalWrite(_startpin+i, !LOW);
}
//delay(3);
}
void SevenSegment::display(int digit) {
for (int i=0; i < 7; i++) {
digitalWrite(_startpin+i, !digits[digit][i]);
}
delay(3);
}
void SevenSegment::selectLED(int pin) {
for (int i=1; i < 5; i++) {
digitalWrite(i, LOW);
}
digitalWrite(pin, HIGH);
}
void loop() // run over and over again
{
SevenSegment digit(6);
digit.selectLED(1);
digit.display(7);
digit.selectLED(2);
digit.display(6);
digit.clearDisplay();
}