Dan's 6502 build, aka, The WOPR Jr.
Re: Dan's 6502 build, aka, The WOPR Jr.
On board specs, you really need to check with the
manufacture you are planning to use. We can
only guess. The one I used last wants a 7 mil annular
ring. Others want less.
On 4 layer, some want more on inner layers.
Dwight
manufacture you are planning to use. We can
only guess. The one I used last wants a 7 mil annular
ring. Others want less.
On 4 layer, some want more on inner layers.
Dwight
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Dan's 6502 build, aka, The WOPR Jr.
Dan Moos wrote:
Ok, I'm leaning more towards having a PCB fabbed instead of DIY. Basically, having a four-layer board with ground and Vcc planes is too convenient. I just about have the thing routed, and I was able to keep the whole thing on a 100 x 100 mm board, which is a serious price point change at PCB way (only place I've looked at so far).
I've always DIY'd my PCBs. I'm worried I won't give them what they need, so I want to check with you guys.
I'm using Kicad. Let's assume that before I create a Gerber, my stuff has passed all ERC and DRC checks.
I've always DIY'd my PCBs. I'm worried I won't give them what they need, so I want to check with you guys.
I'm using Kicad. Let's assume that before I create a Gerber, my stuff has passed all ERC and DRC checks.
Quote:
I'm going with 10 mil traces/10 mil clearance. That seems to be well within the lower price point of places I've looked at, and was something I knew I could DIY if I went that way.
Quote:
What's a good VIA hole/ring size?
Quote:
I wanna make sure I do all the steps. Let's say I've routed, and passed DRC. What else remains? I outlined my board with the User Drawing Layer, but I'm not clear where I actually tell the fab house my intended board dimensions.
- outline gerber file
- legend gerber file
- top soldermask gerber file
- top copper layer gerber file
- 2nd copper layer gerber file
- 3rd copper layer gerber file
- bottom copper layer gerber file
- bottom soldermask gerber file
- drill table excellon file (telling the drill size for each tool)
- drill file excellon file (telling the X-Y coordinates of each hole, and which drill bit to use for it)
If it's for a more-professional board house, I write up a readme.txt file with manufacturing instructions; but DirtyPCBs says don't bother because no one will look at it anyway. If it were for automated assembly of SMT parts, there will also be a solderpaste gerber file (two if you put parts on both sides), and an XYRS for placing the parts; but these two are for the assembler, not the board manufacturer.
I did one prototype board for my work recently with DirtyPCBs too, but they won't do production quantities. It's nice to have these cheap suppliers for simple boards. 25 years ago, a tiny, simple 2-sided board would cost a minimum of $450 for first article—and that was back when that was more money than it is today. The most complex board I ever did (500 parts, 1500 holes, 12 layers) was $2000 for first article, in 1993.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Dan's 6502 build, aka, The WOPR Jr.
Here's the 3D render of the board. I'm going through everything with a fine toothed comb for errors. Don't want to spend money having a dud made!
10 mil tracks/clearances 4 layers, with a GND and VCC plane.
The 3d model for the serial port is not quite what I'll actually have, as I couldn't find a model for the FTDI to serial adapter I'm using. I plan to make a paper printout of the thing so I can check footprints. I also am going to closely compare my schematic to the working specimen on the breadboard.
My dip controlled interrupt lines do take up an inordinate amount of space!
The pin headers with the buses are for easy logic analyzer connection, and for experimenting with adding capability. I notice the raw baud and cpu clocks aren't brought out, but they will be.
The main purpose of this board is to have a rock solid base computer, so that a dodgy breadboard doesn't effect the next phases. It isn't the end game.
10 mil tracks/clearances 4 layers, with a GND and VCC plane.
The 3d model for the serial port is not quite what I'll actually have, as I couldn't find a model for the FTDI to serial adapter I'm using. I plan to make a paper printout of the thing so I can check footprints. I also am going to closely compare my schematic to the working specimen on the breadboard.
My dip controlled interrupt lines do take up an inordinate amount of space!
The pin headers with the buses are for easy logic analyzer connection, and for experimenting with adding capability. I notice the raw baud and cpu clocks aren't brought out, but they will be.
The main purpose of this board is to have a rock solid base computer, so that a dodgy breadboard doesn't effect the next phases. It isn't the end game.
Re: Dan's 6502 build, aka, The WOPR Jr.
Hey guys, quick question...
Implementing a screen buffer for a 80*40 character display. So 3,200 bytes.
What is the "elegant" way to do an array who's indices can't be represented in just 8 bits?
The way I see how to do it doesn't seem terribly efficient, but maybe that's just how it is with an 8 bit processor.
I'd store the address of the current element being worked on in a pointer in 0 page. Lets say I want to go to the next element. I'd INC the value at the location storing the low byte of my pointer, and if it rolls over to zero, I INC the high byte.
Trivial math, but I can't help feeling there is a slicker way to handle such an array.
Is there?
Implementing a screen buffer for a 80*40 character display. So 3,200 bytes.
What is the "elegant" way to do an array who's indices can't be represented in just 8 bits?
The way I see how to do it doesn't seem terribly efficient, but maybe that's just how it is with an 8 bit processor.
I'd store the address of the current element being worked on in a pointer in 0 page. Lets say I want to go to the next element. I'd INC the value at the location storing the low byte of my pointer, and if it rolls over to zero, I INC the high byte.
Trivial math, but I can't help feeling there is a slicker way to handle such an array.
Is there?
Re: Dan's 6502 build, aka, The WOPR Jr.
What if you stored the address in zero page and used the Y register to cycle through: LDA (ZP_ADDRESS),Y? Then you would only need to INC the high byte when the Y register rolls over.
Re: Dan's 6502 build, aka, The WOPR Jr.
If RAM space doesn't matter you can expand the buffer space to either 128 x 40 or 80 x 64. Then multiply becomes a couple of shifts.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Dan's 6502 build, aka, The WOPR Jr.
The Y register is a natural fit for your horizontal counter, but it might be a bit clumsy to have it wrap in the middle of a line. Therefore, my suggestion is to keep a pointer in ZP that points to the address of the left margin of the current line, and don't let Y increment above the width of your line. To calculate the line address, you could just pass it to a small subroutine like this (warning: untested!):
Mike B.
Code: Select all
...
bascalc:
; input: row number [0..39] in A
; output: absolute address of left column in basl/h
; (SCREEN + A * 80)
asl
asl ; multiply line # by eight
asl
rol bash ; sixteen
asl
rol bash
sta basl ; save low half of line # * 16
lda bash
and #$03 ; keep only the valid bits
pha ; from the high half
sta bash
lda basl
asl
rol bash
asl ; we should have line # * 64
rol bash ; in bash:A now
adc basl
sta basl ; low half of line # * 80 in basl
pla
adc bash
adc #SCREEN/256
sta bash ; high half in bash
rts
Re: Dan's 6502 build, aka, The WOPR Jr.
Here's my version:
This uses the fact that the line number is in the range [0, 39], so 5*line number will still fit in a byte. So, multiply the line number by 5, multiply into two bytes by 16, then add the screen base address.
Lightly tested.
This weighs in at 32 bytes. It would be possible to shave off 2 bytes if screen is page-aligned. If speed is more important than size, it may be better to use an 80-byte table holding the start address of each line.
Code: Select all
sta basl ; multiply line number by 5, into basl
asl
asl
clc
adc basl
asl ; multiply by 16, into A, bash
rol bash
asl
rol bash
asl
rol bash
asl
rol bash
adc #<screen
sta basl
lda bash
and #$0f ; keep only 4 lsb of bash
adc #>screen
sta bash
rtsLightly tested.
This weighs in at 32 bytes. It would be possible to shave off 2 bytes if screen is page-aligned. If speed is more important than size, it may be better to use an 80-byte table holding the start address of each line.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Dan's 6502 build, aka, The WOPR Jr.
Ah, well done sir. It was silly of me to not perform the *5 first.
Mike B.
Mike B.
Re: Dan's 6502 build, aka, The WOPR Jr.
Been awhile, but I'm still at it!
I've elected to roll my own video using discrete 7400 logic.
I am basically doing VGA, although the actual resolution I use is still in flux.
Here's the plan, part of which is up and running already.
VGA with a 25.175 MHz pixel clock. Both text and graphics modes.
Right now, I plan to have the controllers native mode be 640 by 480, and to get lesser resolutions, just divide the pixel clock evenly and have it step through video memory at slower rates.
I have perfect Hsync and Vsync pulses up and running using a crystal oscillator, 4 bit chained counters, and 8 bit magnitude comparitors to select specific counts.
I have already purchased dual ported RAM for video memory, and EPROMS for character maps.
I'm looking for a simple, 65C02 compatible method to address my video RAM without cutting into my system RAM's size. Basically, I need simple bank switching.
Simple is the key. I'm thinks something along the lines of having the VIA set a bit on a gate to select system or video memory. Let's limit video memory to 64k for now, although more it's always better.
One thought I had if I could get away with 32k of video memory, is basically to have video and ROM share the same address space, and force all writes to video RAM, and all reads to ROM. This would limit me both in video RAM size, and capabilities (couldn't read video memory), but sounds simple and elegant.
Any kind of color, with a decent resolution needs more than 32k, so that mode is not my go to.
Ideas?
I've elected to roll my own video using discrete 7400 logic.
I am basically doing VGA, although the actual resolution I use is still in flux.
Here's the plan, part of which is up and running already.
VGA with a 25.175 MHz pixel clock. Both text and graphics modes.
Right now, I plan to have the controllers native mode be 640 by 480, and to get lesser resolutions, just divide the pixel clock evenly and have it step through video memory at slower rates.
I have perfect Hsync and Vsync pulses up and running using a crystal oscillator, 4 bit chained counters, and 8 bit magnitude comparitors to select specific counts.
I have already purchased dual ported RAM for video memory, and EPROMS for character maps.
I'm looking for a simple, 65C02 compatible method to address my video RAM without cutting into my system RAM's size. Basically, I need simple bank switching.
Simple is the key. I'm thinks something along the lines of having the VIA set a bit on a gate to select system or video memory. Let's limit video memory to 64k for now, although more it's always better.
One thought I had if I could get away with 32k of video memory, is basically to have video and ROM share the same address space, and force all writes to video RAM, and all reads to ROM. This would limit me both in video RAM size, and capabilities (couldn't read video memory), but sounds simple and elegant.
Any kind of color, with a decent resolution needs more than 32k, so that mode is not my go to.
Ideas?
Re: Dan's 6502 build, aka, The WOPR Jr.
One thing to note re: writing to rom space which I had considered is that you will need to implement hardware scrolling of your vga circuit somehow.
Without hw scroll you won't be able to scroll the screen, if you have r/w access to video ram you can simply move each line up using the cpu.
Without hw scroll you won't be able to scroll the screen, if you have r/w access to video ram you can simply move each line up using the cpu.
-
leepivonka
- Posts: 167
- Joined: 15 Apr 2016
Re: Dan's 6502 build, aka, The WOPR Jr.
Here's some ideas:
Have an 8-bit port supply video memory a15..8. Another 8-bit port to supply video memory a23..16 .
Take 65c02 a7..0 for video memory a7..0 .
Decode a 256 byte (or larger) chunk of 65c02 address space for a video memory access window.
When the window is accessed, run the access on the video memory.
This will give you up to 16MBytes of video memory while using < 1KBytes of 65c02 address space.
If you don't need to read video memory, the window could be the write cycles to 65c02 ROM addresses.
The software that uses this should be no more complex than calculating a 65c02 pointer.
The chargen EEProm could have it's own address space with it's own window & hi address ports,
or could be share video memory address space and use the same window & hi address ports
(maybe video RAM at 0-7MBytes, EEProm at 8-15MBytes),
The video memory address ports could also be expanded & used as a hardware cursor location.
Or the hardware cursor address could have it's own ports. Or you could skip the hardware cursor entirely &
just put a special character in at the cursor location.
Have an 8-bit port supply video memory a15..8. Another 8-bit port to supply video memory a23..16 .
Take 65c02 a7..0 for video memory a7..0 .
Decode a 256 byte (or larger) chunk of 65c02 address space for a video memory access window.
When the window is accessed, run the access on the video memory.
This will give you up to 16MBytes of video memory while using < 1KBytes of 65c02 address space.
If you don't need to read video memory, the window could be the write cycles to 65c02 ROM addresses.
The software that uses this should be no more complex than calculating a 65c02 pointer.
The chargen EEProm could have it's own address space with it's own window & hi address ports,
or could be share video memory address space and use the same window & hi address ports
(maybe video RAM at 0-7MBytes, EEProm at 8-15MBytes),
The video memory address ports could also be expanded & used as a hardware cursor location.
Or the hardware cursor address could have it's own ports. Or you could skip the hardware cursor entirely &
just put a special character in at the cursor location.
Code: Select all
---------- sample programming ---------------------------------
VidRamWindow = $e000 ;256byte window to video RAM
VidGenWindow = $e100 ;256byte window to CharGen EEProm
VidRamAdrM = $e200 ;port for video RAM a15..8
VidRamAdrH = $e201 ;port for video RAM a23..16
VidGenAdrM = $e202 ;port for video CharGen a15..8
VidGenAdrH = $e203 ;port for video CharGen a23..16
VidClear: ; clear video memory
lda #0 ;fill each byte with this
stz VidRamAdrH ;start window at address 0
stz VidRamAdrM
@10: ldy #0 ;fill a 256 byte block through the window
@11: sta VidRamWind,y
iny
bne @11
inc VidRamAdrM ;move window to next 256byte block
bne @10
inc VidRamAdrH
ldy VidRamAdrH
cpy #$4 ;stop after $40000 bytes
bne @10
rts
VidChr8: ; place 8 lines from chargen into video graphics RAM (1 byte per line)
cmp #$20 ;a control-char?
bcc @Ctl
stz VidGenAdrM ;calc CharGen start
stz VidGenAdrH
asl a
rol VidGenAdrM
asl a
rol VidGenAdrM
asl a
rol VidGenAdrM
tax
ldy 0+VidPos ;get video RAM location
lda 1+VidPos
sta VidRamAdrM
lda 2+VidPos
sta VidRamAdrH
@11: ;for each of 8 char lines
lda VidGenWind,x ; copy a line
sta VidRamWind,y
inx ; move to next chargen line
tya ; move to next RAM line
clc
adc #Down1CharLine
tay
bcc @28
inc VidRamAdrM
bne @28
inc VidRamAdrH
@28:
txa ; next line
and #7
bne @11
inc 0+VidPos ;move right 1 char
??? ; handle end-of-line
??? ;place cursor
rts
@Ctl: cmp #$0d ;carriage return?
beq ???
cmp #$0a ;line-feed?
beq ???
cmp #$09 ;tab?
beq ???
cmp #$08 ;backspace?
beq ???
rts ;if unknown, just ignore it
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Dan's 6502 build, aka, The WOPR Jr.
I have never attempted this idea, but I was thinking that you could reserve a couple of side-by-side ZP addresses as a special-purpose video RAM pointer (VRAM, VRAM+1). When your address decoder sees these two addresses being read back-to-back, it assumes that you're doing something like LDA (VRAM),Y or EOR (VRAM),Y and flip-flops your chip-enables from base RAM/ROM/IO to VIDEO RAM until the next SYNC. Jeff knows far more than I (or anyone else I know) about this kind of trickery, and my idea may be full of holes ... maybe he could take a few pot shots at my idea, or provide one of his own?
Mike B.
Mike B.
Re: Dan's 6502 build, aka, The WOPR Jr.
barrym95838 wrote:
When your address decoder sees these two addresses being read back-to-back, it assumes that you're doing something like LDA (VRAM),Y or EOR (VRAM),Y and flip-flops your chip-enables from base RAM/ROM/IO to VIDEO RAM until the next SYNC.
The idea of waiting for SYNC has a real advantage when it comes to simplicity, but you'd hafta be careful with the circuit design if you're aiming to run the system at the maximum possible clock rate. SYNC isn't guaranteed to go high until tADS after the beginning of the cycle. So, if you're relying on SYNC to say when normal (ie using base RAM) operation resumes then you could end up delaying the resumption of normal operation (thus limiting the maximum clock rate at which you can expect reliable operation). There are ways to work around this. tADS also applies to address lines A15-A0, so the trick is to deal with SYNC concurrently.
Another solution is to mostly ignore SYNC, and instead always allow a 2-cycle, fixed-duration time slot immediately after the back-to-back read of the two zero-pg addresses. As noted, a write (ie, STA) is going to be 2 cycles in any case. As for reads, you'd still allow 2 cycles but if SYNC goes true on the 2nd cycle (ie, there was no page crossing) your logic would just pull RDY low to briefly delay the CPU. RDY doesn't need to be valid until late in the cycle, so the tADS delay doesn't matter. And the inefficiency of those occasional wasted cycles might well be justifiable if it avoids the necessity for an overall decrease in clock rate.
FWIW, this (ind),Y scheme you propose has similarities to what the MOS 6509 does. But your scheme engages extended memory only when a certain zero-page pair is used, whereas the 6509 engages extended memory for all LDA (ind),Y and STA (ind),Y accesses. IOW it doesn't care which zero-page pair is used but it does care about the instruction (and the address mode, of course).
cheers,
Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: Dan's 6502 build, aka, The WOPR Jr.
Hi gang!
I'm still at it. Currently working on my video controller. I'm doing VGA, with 640x480 60 Hz timing, but will actually do a much lower resolution. I currently have my Hsync,Vsync, and blanking intervals up and running. All done with 74HC logic. Works great.
Now working on my text mode. My plan is have my 8x12 font arranged so that the fonts are broken up into their horizontal lines, and stored that way in ROM. In other words, if I have a row of text to display, I send the characters to the ROM, which will see them as an address corresponding to the correct bitmap for the first horizontal line of each character. I will then increment to another page in ROM, and do it again. 12 times for every row of text. I imagine I can't be the first to think of this method, as I can't think of an easier way do text. Is this how its usually done in a non-graphics mode?
I have 64k of dual ported SRAM for my video memory. My current plan is to simply connect AND gates to the chip enables and write enables of the system RAM and video RAM, and use I/O from the VIA to choose which is selected. I imagine I'll have to do a little more cleverness than that since the VIA itself is in system RAM address space. I'm also considering memory methods previously brought up in this thread.
BUT....my current issue is creating the font. I can think of 5 ways:
Manually typing hex or binary into my ROM burner software (sounds tedious, but maybe not too bad)
Finding some piece of software to covert Windows fonts into the form I need. No luck yet.
Creating font drawing software using Visual Basic or C# or the like, such that the GUI parts of the development are pretty much drag and drop. Normally I shun that kind of "programming", but needing a quick UI for doing a programming-wise simple task seems like what those things were made for. This actually could be fun. Leaning this way currently.
Finding such a piece of software already made.
Finding fonts online that are stored as a simple binary bitmap, preferably in the page per line format I mentioned.
Any thoughts? My first choice would be any method that lets me create my own font so I can give it a little flare!
I'm still at it. Currently working on my video controller. I'm doing VGA, with 640x480 60 Hz timing, but will actually do a much lower resolution. I currently have my Hsync,Vsync, and blanking intervals up and running. All done with 74HC logic. Works great.
Now working on my text mode. My plan is have my 8x12 font arranged so that the fonts are broken up into their horizontal lines, and stored that way in ROM. In other words, if I have a row of text to display, I send the characters to the ROM, which will see them as an address corresponding to the correct bitmap for the first horizontal line of each character. I will then increment to another page in ROM, and do it again. 12 times for every row of text. I imagine I can't be the first to think of this method, as I can't think of an easier way do text. Is this how its usually done in a non-graphics mode?
I have 64k of dual ported SRAM for my video memory. My current plan is to simply connect AND gates to the chip enables and write enables of the system RAM and video RAM, and use I/O from the VIA to choose which is selected. I imagine I'll have to do a little more cleverness than that since the VIA itself is in system RAM address space. I'm also considering memory methods previously brought up in this thread.
BUT....my current issue is creating the font. I can think of 5 ways:
Manually typing hex or binary into my ROM burner software (sounds tedious, but maybe not too bad)
Finding some piece of software to covert Windows fonts into the form I need. No luck yet.
Creating font drawing software using Visual Basic or C# or the like, such that the GUI parts of the development are pretty much drag and drop. Normally I shun that kind of "programming", but needing a quick UI for doing a programming-wise simple task seems like what those things were made for. This actually could be fun. Leaning this way currently.
Finding such a piece of software already made.
Finding fonts online that are stored as a simple binary bitmap, preferably in the page per line format I mentioned.
Any thoughts? My first choice would be any method that lets me create my own font so I can give it a little flare!