Page 1 of 1
Best way to learn 6502 assembly without real hardware?
Posted: Sun Aug 14, 2005 9:57 am
by Lazy1
Is it possible to learn 6502 assembly on my pc?
I have several apple IIs lying around but the keyboards are not friendly when it comes to lots of typing - that and the small screen size.
After learning how to program for the 6502 I'd like to build a small computer, what can you recommend for someone who knows a bit about electronics but nowhere near enough to build something useful?
Thanks.
[Edit]
Oops, forgot to look on the tools page...
I found a simulator but what about building 6502 based computers?
Re: Best way to learn 6502 assembly without real hardware?
Posted: Sun Aug 14, 2005 4:05 pm
by kc5tja
Oops, forgot to look on the tools page...
I found a simulator but what about building 6502 based computers?
The best way to learn how to build a 6502 based computer is to first learn these two things:
* Basic digital electronics
* Digital electronics timing analysis (which is the key to learning more advanced digital electronics stuff anyway)
Once you learn those two things, then you're ready to basically just dive right in. There is no right or wrong way to build a 6502-based computer.
You're free to look at my Kestrel project as an idea generator, although I used the 65816 processor because I wasn't forced to place RAM in the low addresses like the 6502 forces. Which should be a good idea for you to look at anyway, because a very handy skill to learn is how to generalize concepts off of reading other people's schematics.
http://www.falvotech.com/projects/kestrel/1p3.php
Posted: Sun Aug 14, 2005 7:53 pm
by Lazy1
Thanks for the info, any specific books/sites you can recommend?
Still learning 6502 asm, the site I looked at didn't explain the code samples very well but I picked up enough to do this:
Code: Select all
.ORG $200
Hello: .ASCII "Hello!", $00
.START .Main
.Main LDY #$00 ; String indexer
.getch LDX Hello, Y ; TODO: String address
BNE .prtch ; If this is a valid character print it to the screen
BEQ .fin ; Null terminator? End this now
.prtch TXA ; Transfer X to the accumulator
STA $E001 ; Write the character stored in the accumulator to the screen
INY ; Point to the next character
JMP .getch ; Grab the next character
.fin BRK ; Ends execution?
Anything completely wrong in there?
Thanks for the help so far.
Posted: Sun Aug 14, 2005 9:08 pm
by kc5tja
Code: Select all
.ORG $200
Hello: .ASCII "Hello!", $00
.START .Main
.Main LDY #$00 ; String indexer
.getch LDX Hello, Y ; TODO: String address
BNE .prtch ; If this is a valid character print it to the screen
BEQ .fin ; Null terminator? End this now
.prtch TXA ; Transfer X to the accumulator
STA $E001 ; Write the character stored in the accumulator to the screen
INY ; Point to the next character
JMP .getch ; Grab the next character
.fin BRK ; Ends execution?
Anything completely wrong in there?
Thanks for the help so far.
Nothing is inherently wrong with the code, except that it wastes some amount of time using registers that it doesn't need to use. I would write the above like this instead:
Code: Select all
.ORG $200
Hello: .ASCII "Hello!", $00
.START .Main
.Main LDY #$00 ; String indexer
.getch LDA Hello, Y ; TODO: String address
BEQ .fin ; Null terminator? End this now. Otherwise . . .
.prtch STA $E001 ; Write the character to the screen
INY ; Point to the next character
JMP .getch ; Grab the next character
.fin BRK ; Ends execution by invoking the system debugger.
Notice that I did away completely with using the X register, because loading the A register sets the CPU's flags properly too. Also, I eliminated the BNE instruction because, logically, if BEQ didn't work, it must be non-equal, and so we "fall through" into the .prtch routine. A already holds the character to print, so we just store it in the output register (I'm assuming this is some kind of simulator parallel port?).
Posted: Sun Aug 14, 2005 9:27 pm
by Lazy1
Thanks for the tip, and yes, writing to $E001 in the simulator outputs a character to a display window.
Posted: Sun Aug 14, 2005 9:35 pm
by GARTHWILSON
> I have several apple IIs lying around but the keyboards are not
> friendly when it comes to lots of typing - that and the small screen size.
Have the keyboards gone bad? When you get more advanced, you'll want to be able to use a full-featured text editor and a nice macro assembler; but those are not at all necessary just to start. Some of us started on the AIM-65 which, although it had a querty keyboard, only had a one-line, 20- or 24-character display, and a little printer built in that resembled a supermarket receipt printer.
There are a lot of resources on this website, and a lot more on the way (even if they are slow in coming).
Posted: Sun Aug 14, 2005 9:47 pm
by Lazy1
The keyboards aren't broken, they just have the keys too close together.
The other thing is my only apple II assembly book gives you a broken assembler to work with and the code in the book uses commands only their assembler understands.
I'm still looking for more tutorials though, the one I found was pretty brief and didn't cover things like interrupts or the stack.
I'll keep looking.
Posted: Tue Aug 16, 2005 10:04 pm
by Lazy1
I have been reading through my 6502 book and some examples required display memory to write to inorder to change the screen.
Since the simulator I'm using does not have any display memory I decided to emulate it starting at $200 until $3B8 which should fill the simulator display console.
I'm surprised it actually worked but there is a bug when I try and copy from the other vram page.
Like, I load the display base address's high byte into the accumulator ( $02 ) and then I add 1 to it inorder to point to the next page.
For clearing the screen this works, when writing the screen contents to the simulator's console output address ADC produces $04 in the accumulator instead of $03 which it does in the screen clear code.
Sorry if the code is ugly and it will be hacked together as I haven't gotten that far into the book.
Code: Select all
.ORG $00
DisplayWidth: .DB $28
DisplayHeight: .DB $0B
DisplayBaseAddr:.DW $200
DisplayEndAddr: .DW $3B8
DisplaySize: .DW $1B8
DisplayPos: .DW $00 ; Counter for screen display ( 16 bits )
Test: .ASCII "This is a very long string used to test the emulated display memory, will it work? Who knows....", $00
.START Main
; Linear display memory emulator
; Emulated video memory starts at $200 and extends to $3B8
; HACKHACKHACK
; Testing purposes only
Main JSR EmuDisplayClear
LDY #$00
.NextCh LDA Test, Y
STA (DisplayBaseAddr), Y
BEQ .Fin
INY
JMP .NextCh
.Fin
LDA #$41
STA $305
NOP
NOP
JSR EmuDisplayCopy
BRK
; Clears out the emulated video memory
; ======================================
EmuDisplayClear ; Clear the first page of VRAM
LDA #$00 ; Load 0 into the accumulator
LDY #$00 ; Load 0 into the Y register
.ClearWriteToVRAM1 STA (DisplayBaseAddr), Y ; Use DisplayBaseAddr as a pointer and store the accumulator into VRAM
INY ; Next byte
BEQ .ClearRemainingVRAM ; Did we roll over the Y register? If so, clear the remaining VRAM
JMP .ClearWriteToVRAM1 ; Finish clearing VRAM
.ClearRemainingVRAM LDA DisplayBaseAddr + 1 ; Load the high byte of the VRAM address into the accumulator
ADC #$1 ; Add one so we point to the next page
STA DisplayBaseAddr + 1 ; Write back the modified pointer
LDA #$00 ; Reset the accumulator to 0
.ClearWriteToVRAM2 STA (DisplayBaseAddr), Y ; Write the accumulator into VRAM
CPY DisplayEndAddr ; Have we reached the end of VRAM?
BEQ .ClearCleanup ; If so, clean up what we changed
INY ; Next byte
JMP .ClearWriteToVRAM2 ; Finish clearing VRAM
.ClearCleanup LDA DisplayBaseAddr + 1 ; Load the high byte of the VRAM pointer
SBC #$1 ; Subtract one so we go back to the page it starts on
STA DisplayBaseAddr + 1 ; Write back the pointer
RTS ; Return to caller
; Writes the emulated video memory to the simulator's console output address
; =============================================================================
EmuDisplayCopy ; Write the first page of VRAM to the simulator console
LDA #$00
LDY #$00
.CopyCopyVRAMPage1 LDA (DisplayBaseAddr), Y
INY
BEQ .CopyRemainingVRAM
STA $E001
JMP .CopyCopyVRAMPage1
; BUGBUGBUG
; LDA DisplayBaseAddr + 1 Loads 02 into the accumulator, yet
; ADC #$1 causes the accumulator to read 4 instead of 3
.CopyRemainingVRAM LDA DisplayBaseAddr + 1 ; Load our VRAM pointer's high byte into the accumulator
ADC #$1 ; Add one to set the next page
STA DisplayBaseAddr + 1 ; Save the modified pointer back into ram
.CopyVRAMPage2 LDA (DisplayBaseAddr), Y
INY
BEQ .CopyCleanup
STA $E001
JMP .CopyVRAMPage2
.CopyCleanup LDA DisplayBaseAddr + 1
SBC #$1
STA DisplayBaseAddr + 1
RTS
Posted: Wed Aug 17, 2005 2:05 am
by kc5tja
In general, before using ADC, you should use CLC to clear the carry bit. Not using CLC is OK as long as you can absolutely be sure that the carry bit is clear. Conversely, if the carry bit is guaranteed to be set, you can just ADC #$00 to increment the A register.
Re: Best way to learn 6502 assembly without real hardware?
Posted: Thu Sep 08, 2005 4:15 am
by asmlang_6
Oops, forgot to look on the tools page...
I found a simulator but what about building 6502 based computers?
Once you learn those two things, then you're ready to basically just dive right in. There is no right or wrong way to build a 6502-based computer.
Here's some tips:
- Wire your system together on a breadboard. You can easily insert/remove components without soldering, and they will stay on pretty good (I was building a 6502 system on a breadboard, and I turned the breadboard upside down and none of the components fell off!). But one warning: don't put the parts in too good, or you will have lots of frustration when trying to remove chips.
- Take your time to make a memory map. Since the 6502 uses memory-mapped I/O, you will have to factor that in. Most 6502 systems use the 74LS138 3-to-8 decoder for memory mapping (usually priced at around 50 cents). The 74LS138 is connected to the 6502 by wiring lines S0, S1, and S2 (pins 1, 2, and 3 respectively) to A15, A14, and A13 (note: counting from A0 here) on the 6502. Then, connecting /Y1 to /CS of a chip should map it to $0000-$1FFF, /Y2 to $2000-$3FFF, etc.
Posted: Tue Sep 13, 2005 2:46 pm
by Lazy1
Thanks for the info but I don't understand quite a bit of what you said.
Still learning 6502 assembly after a short break so once that is done hopefully I can learn how to build something which uses it.
6502 sim for learning basics
Posted: Sun Sep 18, 2005 5:05 am
by djmips
http://home.pacbell.net/michal_k/6502.html
This is a simulator for your PC. You can write small code, it will assemble and you can step through the results.
Posted: Sun Sep 18, 2005 11:32 pm
by Lazy1
Yeah, thats the simulator I'm using now which didn't support display memory which is why I had to emulate it.
Actually, I should probably re-write that along with some printf and console routines.
printf and console
Posted: Mon Sep 19, 2005 12:30 am
by djmips
Check out the liba.65s example for input/output to the In/Out window. I agree that it's not the best and if it had better I/O and graphics output that would be a lot of fun.
Posted: Mon Sep 19, 2005 9:00 am
by Memblers
I learned 6502 by running my programs on NES emulators. I can use the real hardware now that I built my own cartridge.
If you're willing to learn the quirks of that system (which is mostly related to the graphics), it's a good one to use. NMOS 6502 (no decimal mode though), good sound, decent tiled graphics/scrolling, and 64 sprites. It's also very common hardware if you want a real one (and many companies still make clone systems today).