After reading some Atari documentation and also seeing some of the documentation for the 84+C, the way I saw what was considered "acceptable" assembly completely changed. For the past few years, I have procrastinated on this project of mine, but last night I started from scratch and it is almost finished.
I have basically created an emulator for a processor that doesn't exist. I created the instruction set to emulate and the ports. I originally modeled instructions and interactions based on how the z80 does it and so the process of completing the instruction set was tedious. I completely changed my approach and here are the stats:
The instruction set is 6-bits, so there is room for 64 instructions but not all are finished. You have 256 bytes of RAM, the first 42 bytes (it will probably be more before this is finished) is for interacting with ports and the last 128 bytes is for a stack. There are 512 bytes of code space and there are
no registers. This was the main spark of insight I had last night. Instead, you work directly with the RAM. Here are the instructions currently emulated:
Note that all values are 1-byte.
ld (addr1),(addr2) loads a byte from one RAM address to another.
ld (addr),const loads a byte into the RAM address
add (addr1),(addr2) adds two bytes of RAM together, storing the result to the first byte. Modifies C and Z flags
add (addr),const adds the constant value to the byte. Modifies C and Z flags
You get the idea, I am sure, so here are others that follow the same structure:
adc
sub
sbc
xor
or
and
cp (compare two values)
And these are some more:
inc (addr)
dec (addr)
push (addr)
push const
pop (addr)
ex (addr1),(addr2) ;exchange two bytes
ret
ret z
ret c
ldir (addr),size,data ;copies inline data of the given number of bytes to a ram location specified by (addr)
ldir const,size,data ;copies inline data of the given number of bytes to a ram location specified by (addr)
It is important to note that the
ldir commands are very useful for setting up the ports.
there are also the jrf, jrb, callf, and callb commands. Each of these can work on a condition of c or z (not nc or nz).
jrf jumps forward a given number of bytes.
jrb jumps backwards a given number of bytes.
callf calls a relative routine that is within 256 bytes ahead
callb calls a relative routine that is within 256 bytes behind
Anytime a relative jump or call is made, it will never execute code from RAM. If you go past the 0~511 byte code range, it will loop back around.
There are 8 sets of 4 ports for sprites. The ports are ordered:
LSB of sprite data
MSB of sprite data
X coordinate
Y coordinate
In all, these makeup the first 32 bytes of RAM
Port 20h is the Sprite Update Port. When a sprite is drawn, its corresponding but gets set here. You can reset all of the bits here, then read from it to figure out when all of the sprites have been drawn.
Port 29h is the Sprite Mask Port. Set the corresponding but here to have the sprite drawn. Compare this port to port 20h to see if all the sprites are drawn.
Ports 21h~27h hold values for keypresses
Port 28h is the Key Mask Port which determines which groups of keys get polled
2Ah holds the stack pointer.
Anyways, I would offer an upload or something, but I cannot get it off of my calc, once again. Also, it is currently written in Grammer code, but I plan to convert it to an assembly program. My first attempt is going to make a Pong game and all I currently have done codewise setting up the ports All of the mentioned instructions work by the way, all I need to do is emulate the ports