Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange

Hot answers tagged

108

One use is as a copyright mechanism. Many distributors would steal/copy programs and sell pirate or derivative copies, by changing the text strings inside the code and reordering the blocks, it was hard to prove the code had been stolen. Placing noops of different types you could put a signature sequence which was much easier to detect and hard to hide. A ...


68

The NES was also from the era where some sound and graphics resources were also executable code. (Typically, this worked the other way around. Identify a needed sound and listen to chunks of the binary to find a reasonable candidate.) Injecting NOPs can improve the look or sound derived from a section of executable. Example: "One of the more-challenging ...


42

Sinclair didn't always use the Z80 for its computers. The MK14 computer, sold in kit form (like the ZX80 was), used a National Semiconductor INS8060. The ZX range of home computers have a video display hardware that is very closely tied to the architecture of the Z80. On the two first models, ZX80 and ZX81, the video display hardware was kept to a minimum, ...


39

The 6502 CPU is just one piece of the puzzle Emulators emulate entire machines, not merely CPUs. Even the likes of QEMU emulate an entire generic computer. It helps if you think of the Apple II and NES not as singular units but as networks of components. The CPU, graphics unit, RAM and so on all have communications to each other and do so at a very fast ...


34

I'm just speculating here, but one possible reason for using a 2-byte NOP would be if you wanted to change an existing 2-byte instruction into a NOP (to fix a bug, for instance), without changing the byte count for the instruction. (An undocumented 2-byte NOP might execute more quickly than two standard 1-byte NOPs in succession.) You might do this to ...


31

There are many answers to this and none might satisfy you. First of all, an Emulator doesn't just do a CPU, but a machine. The same way you can't run an NES game on an Apple II. So while one may do multiple ones, different can do the hob as well. Furthermore, there are different target platforms. Linux isn't Windows which again isn't MacOS and so on. Like ...


30

A mistake? The instruction $89 on the 6502 is a two-byte NOP. Based on adjacent instructions in the opcode matrix, especially LDA #ii ($A9 ii), it would have been STA #ii, a store to an immediate value, which makes no sense. On the 65C02, this instruction is changed to BIT #ii, which almost behaves as a two-byte NOP. One hypothesis is that a programmer ...


30

MADS uses * in three ways (See MADS "Manual") Using the current assembly address for calculation of an address, i.e. the one the actual statement is assembled to. Multiplying in expressions. Mark the beginning of a comment (until line end) In above listing it will be interpreted as the address the JMP instruction is assembled to, so it will form an ...


28

An instruction set can be considered as a Huffman coding of an idealised instruction stream. So the question is really asking which CPUs have a good balance of short encodings for common tasks to longer encodings for rare tasks. However, it is not sufficient to just look at the encoding of individual instructions because a RISC instruction generally does ...


27

First, for Commodore's part, it should be obvious the reason for choosing the 6502 microprocessor for all their 8-bit machines (notwithstanding the dual-processor CBM 9000 and C128) - Commodore owned MOS. Jack Tramiel was very focused on vertically integrating his manufacturing, which basically assured Commodore's use of MOS CPUs and support chips. Since ...


25

The 6502 had 16-bit addressing but only an 8-bit adder. For an indexed load or store, the index register had to be added to the base address in two steps. As an optimization, the 6502 will load from memory as soon as the first part of the add is complete. If the add didn't cause a carry out, the loaded value is kept. If it did cause a carry, the value is ...


22

If you look at the screen clear code in the Applesoft BASIC ROM, you'll find this: f3f6 lda $e6 ;put base address of current hi-res page sta $1b ; into $1a/1b (will be $2000 or $4000) ldy #$00 sty $1a f3fe lda $1c ;get color value sta ($1a),y ;store it in frame buffer jsr $f47e ;...


22

The code you've posted: loads the immediate value 0 into A; loads the immediate value 3 into Y; then compares the 0 in A to whatever is in memory at the address you've given the label Y. There are no register-to-register comparisons on the 6502.


21

The MOS 6502 (1 MHz) was introduced in 1975 for a price of $25. Then in 1978 MOS agreed to sell the 6502 (1.79 MHz) and an IO chip to Atari for $12 per set (because the production cost was $4). In 1977, the Zilog Z80A (4 MHz) was $65 for the ceramic package and $59 for the plastic version.


20

This is explained in “Add a trap vector for unimplemented 6502 opcodes” by Carl W. Moser, published in Dr. Dobb’s Journal volume 4, page 32 (page 42 in the PDF; this is linked from the Wikipedia article on the 6502). The 6502 outputs a sync pulse on pin 7 whenever it reads an opcode, but not when it’s reading anything else (the second or third bytes of an ...


20

To a certain extent you can guess the number of cycles by counting the number of memory accesses. A 2-byte instruction will take a minimum of 2 cycles because you need to read 2 bytes. If the instruction needs to read or write a data byte add another cycle. For example, a zero-page read is a 2-byte instruction, but in addition to reading the instruction ...


18

First, you need to clear carry before doing an ADC to avoide that a random value of Carry is added. Second, since your numbers are unsigned, Carry is what you're looking for, not Overflow. When adding a Carry is produced every time a result does not fit in a single byte. Overflow is only needed when doing signed numbers. What you want to do should look ...


18

Without issuing a CLI, no further interrupts can occur (until EOI, at least, where flags are restored by the RTI instruction). As this is a raster interrupt, you need to acknowledge that as well for another one to happen, which the seemingly benign $D019 manipulation achieves earlier in the interrupt handler, cf. the linked FLI routine. In this specific ...


18

That's a usual way to an indirect JSR with a 6502. The 6502 does not support indirect subroutine calls (*1), so it has to be done in software. Indirect subroutine calls are a useful tool for function calls into OS/library functions which may change during runtime or by configuration - like when redirecting output to a different driver. By using a routine ...


16

I've done this partially with Commodore PET Space Invaders which I used as a test program to debug my Commodore PET emulator. I used a disassembler to convert the program to assembly language and I then went through the code annotating it as I found out what it does. When I understood what a bit of code did, I would look for its entry point (my disassembler ...


16

While @dirkt's is a good answer, I think it might be missing the high-level overview you're after. On the most basic level, instructions using immediate vs absolute addressing are encoded into different opcodes. For example, LDA # (immediate mode) is encoded as A9 (after which the CPU knows, by mechanisms detailed in @dirkt's answer, to read one byte and ...


16

Somewhat of a guess: The C64 always interleaved CPU and graphics RAM access (with additional graphics cycles if necessary), effictively accessing RAM at 2 MHz. Judging from the ANTIC Timing Diagram, the ANTIC just stole CPU cycles whenever it needed them. So in both cases you have a RAM access of about 2 MHz, which seemed to have been the limiting factor....


16

The PDP-8 was a 12-bit computer with a deliberately simple instruction set. That's part of your answer right there: the 6502 was in many ways more complex than the PDP-8: the 6502 has 56 machine instructions, but the PDP-8 has only 24.¹ The base configuration of the original PDP-8 simply offered less power in its half rack of space than the 6502 does in ...


15

Quick shot, without looking it up in Visual 6502 (which would be the authorative option): Sign extend the branch offset (replicate MSB of offset), that will tell you the ALU input for the PC high byte. Possible values are 0 and -1 (all 1s), these are available as constants. Carry and sign of the branch offset together determine if an extra cycle is ...


14

The Ricoh 2A03 (NTSC) and 2A07 (PAL) are best thought of as ASIC devices. They include a 6502-compatible CPU core, but these chips also include the NES's 5-voice Programmable Sound Generator. The inclusion of the PSG, plus other I/O interfaces for the NES, together resulted in 22 internal memory-mapped I/O ports that are on-chip. As you mentioned, the binary-...


14

There is a C compiler for the 6502 CPU (cc65). The wiki for this compiler has a section about the internals of the compiler itself, in which the argument passing and result return is discussed. As the wiki has a CC by 3.0 license, I can copy and redistribute the documentation inside that wiki, for the sake of completeness, provided that appropiate credit is ...


14

I suspect the * means the current instruction/location, as it does in some other assemblers, like PDP-8.  Often it would be used in an expression like *-label in the data section to get something's size, or *+3 perhaps, in code. If that's the case for 6502 assembly, then jmp * means branch to self, or, infinite loop, which would be a form of halting ...


14

I think it's xa (xa65): ☑ #include "foobar" ☑ define the address to be assembled to via *=$1234 ☑ define labels without a colon ☑ Comments are marked with a leading ; ☑ specifying characters as constants such as in lda #'A' — the example given in the manual uses double quotes (lda #"A"): is that a disqualifier? ☒ .pet pseudo-op to include PETSCII-encoded ...


13

On the 6502, it's pretty common for code to use the BIT instruction to skip over bits of code; the most common usage pattern is skipping over a 2-byte instruction using a 3-byte BIT, but the approach could also work skipping over a one-byte instruction with a 2-byte BIT. For example: EnterWithCarrySet: sec db $24 ; Bit ZP EnterWithCarryClear: ...


13

As noted, the 6502 has only single 8-bit adder, plus a special increment circuit for the top half of the program counter. Having a full 16-bit adder would avoid the page-boundary penalty for branch instructions, but wouldn't help with indexed loads. By the time the CPU fetches the upper byte of a base address, the 8-bit ALU will have already done ...


Only top voted, non community-wiki answers of a minimum length are eligible