One of the big reasons I was interested in this job in the first place is now being phased out.
Oh well, I guess I’ll just add it to the pile of things to consider every day when I start thinking about how sick and tired I am of working nights.
One of the big reasons I was interested in this job in the first place is now being phased out.
Oh well, I guess I’ll just add it to the pile of things to consider every day when I start thinking about how sick and tired I am of working nights.
So, I began some preliminary design work on WeatherMan the other day. For this first run I’m probably going to use the UIKit navigation tools for organization. I don’t know whether or not I’ll stay with them, depending on how things look down the road.
For the most part, the program will be fairly straightforward. All data will originate from the National Weather Service. The program will need to be able to take location data (supplied either by the user in the form of city/state or zipcode, or supplied by CoreLocation) and translate it to figure out the correct NWS zone. From that point, it’s a pretty simple retrieval of data from the NWS public access servers, and then format that data for the user. There will probably be a backend hosted on my Dreamhost account to take care of much of the heavy-duty work.
While most of this will be straightforward, there are two or three specific things that will need some major work:
As far as sending the data out, it’s not an option at all until Apple implements their notification services. After that time, we’ll see. I’d like to be able to target specific users with specific notifications if I can, but at the same time I’d like the application to be useful from first launch, without the need for registration or anything of that nature. Again, a moot point until the time arrives that these notifications can be pushed out at all.
Due to the costs associated with running this service (Apple’s developer fee, the access fee for the weather notifications, and the possibility of more hosting charges if this thing gets bigger than I think it will and Dreamhost kicks me off of shared servers), I will definitely be charging for this application. The price will be no higher than $4.99, and I’m actually leaning toward $.99 or $1.99. This will allow me to recoup costs associated with keeping this running without introducing a huge cost barrier to the consumer.
This is the saddest thing I have heard in a very long time:
(CNN) — The Dallas, Texas, school district laid off hundreds of teachers Thursday to avoid a projected $84 million deficit.
[...]
The district laid off 375 teachers and 40 counselors and assistant principals Thursday, and transferred 460 teachers to other schools within the district.
What makes this worse is that I’d make a fair bet that the majority of those teachers are art, music, and other “non-essential” subjects. What I want to know is, how do you make an error like that and still have your job? Sickening. Because of somebody’s math error, these students are going to suffer for the rest of their lives.
I was reading through iFixit’s disassembly of the new MacBook, and found this little gem, in reference to the new battery latch which is not a coin-turn one like the old ones:
“For those hurt by the financial crisis, a coin is no longer required.”
So, I’d kind of like to incorporate a few “widgets” into the design… just a few little icons, like the current weather, a Minnesota scoreboard, maybe something with World of Warcraft… I’m just having trouble figuring out where to stick them without ruining the design.
So, a little more on CocoNES’s 2A03 core. But first, a general idea of where I’m going with this. I’ll be running two threads–one is the event dispatch thread with the main event loop, and then the virtual machine itself will run on a secondary thread. The VM loop is really fairly simple; the first thing that happens in the loop is the -pulse message is sent to each timed component (ATM, the CPU and PPU). The CPU only receives the -pulse message every third cycle, as the CPU runs at 1/3 the speed of the PPU; this will give cycle-exact accuracy. The other part of giving cycle-exact accuracy was accounting for the fact that each CPU instruction actually takes multiple cycles to execute, and making sure the correct data, address, and control lines are set for each cycle. I spent a lot of time trying to figure out how I could do this, and came up with a pretty decent solution, I think.
The actual CPU itself has a timing control unit that keeps track of where the instruction is in its processing. I used the same idea in my emulated version; the CPU is kept in a static state between pulses, and each time a pulse is received, the next cycle is executed and the CPU is kept in state. I was actually able to easily handle the slight overlap in instruction (the next instruction is fetched as the current finishes executing); it was very easy when I realized that the CPU still only had one data latch and one address bus, so I could still only grab one piece of information at a time. So, while the last instruction is executing, I’m getting the opcode for the next instruction, then I reset the cycle counter to 1 instead of 0, signifying that the instruction is already stored in the instruction register and ready for execution.
In order to cut down on overhead, I came up with what should be an overhead-light “addressing” solution. Basically, there’s two components to each opcode, the addressing mode and the operation itself. So, what I ended up doing was making two arrays, one for the addressing mode and one for the operation. The opcode itself is just a simple 8-bit byte, so I can use the value of the byte as the index of the array; for example, if the opcode is $EA (which happens to be the No Operation code), I can look up addr_modes[0xEA] and instructions[0xEA].
But, you may ask, what ARE those arrays of? Well, I figured out early on that the Objective-C messaging overhead would probably be too much for this task. So I went searching for an alternative. I had originally thought to just write it in straight-up C with Core Foundation, but in the end I came up with a better solution. Objective-C is a strict superset of C–that means any C code works in an Objective-C environment, and that Objective-C is completely based off of standard C components. I was able to use this fact to realize that somewhere in there, there must be pointers to all of these methods. Cocoa specifies the IMP type (implementation pointer) that points to the implemented methods, that can then (with a couple of normally hidden arguments) be called as normal functions. So I was able to typedef a couple of custom types, and each array is an array of pointers to the functions. So, when the CPU receives a pulse, it runs addr_modes[opcode](), which starts the process of retrieving data, and then calls operations[opcode]() when it’s time to do the dirty work.
As soon as I have a chance to test the code more and clean it up a bit (as well as comment it some more) I’ll post a link to the source, since it can probably explain what’s going on far better than I can.
Well, since I’m currently being kept awake by my upstairs neighbors (who have apparently conspired to keep me awake a lot lately), I guess an update is in order.
I think that’s about it.
Well, I think I’ve come up with a more than suitable solution for CocoNES’s CPU emulator. It will remain an Objective-C class to facilitate variable scope limiting and other object-oriented goodness, but will take an advantage of a low-level method of NSObject that will return a method implementation pointer, which is basically a pointer to the actual C function that a method is built on. When the CPU object is initialized it will create a C array of these pointers with the index of each instruction being the same as the opcode for that instruction, so I can do a simple opcodes[current_opcode](); to run the opcode.
The CPU object will have an instruction counter that is incremented with each cycle of an instruction; each instruction will contain a switch() block that will take it to the correct place in the execution, so I can synchronize the CPU and the PPU. Basically I’m trying to make it act like the real thing, where the state is held until the next clock pulse. Then I can do the cycle on both the PPU and CPU, and make sure the correct data is on the data and address buses for the next clock pulse.
Colin’s comment on my last post about CocoNES got me thinking, and now I’m strongly leaning toward abandoning Cocoa for the 2A03 and 2C02 parts and writing them in straight-up C with Core Foundation. This should help keep the overhead low while still letting me insert the cores easily into the virtual machine and ultimately the Cocoa shell.
My only concern about following that method would be the threading. I’m still hammering out the details of how I want that to work. There are two things that seriously complicate matters: first, each instruction takes multiple clock cycles. Secondly, like most 8-bit MPUs the 2A03 (6502, for all intents and purposes) has some minor parallelism going in where for most (but I don’t believe all) instructions the opcode for the next instruction is fetched while the current instruction finishes execution. My main concern is that I need to have the correct address and data on the buses at the right time; that’s probably the most complicated part of this whole endeavour until I need to do optimization. I already know for sure I’m going to launch one thread for the entire virtual machine so it doesn’t block the event loop. Do I want to launch separate threads for the 2A03 and 2C02? Do I need two threads to account for the parallelism in the 2A03? If so, how do I go about that?
I will say though that my investigations into CF (thanks again, Colin!) have given me one good idea. I was originally planning to use a switch() block to decode the opcode, but now I’m thinking I can make an array of pointers to functions, since it looks like I’ll be using pure C for the core. That will seriously cut down some branch work, and should be very easy to implement since 1) all opcodes are void functions with no arguments and 2) opcodes are just 1-byte numbers, so I can read the opcode and voila! Array index!