6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 16, 2024 8:52 am

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Fri Jul 10, 2020 11:24 am 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
Hi,

I've been having weird issues with my monitor rom that I've finally tracked down to the Timer not running at the right rate but only in some cases.

If I add anything at all anywhere before "STA DUARTCRA" (like a NOP or even a bunch of code) it works fine but without it (as shown below) it ticks very slowly causing a 1 second timeout to take 7 seconds instead

What's really weird, is that I can fix this by adding a NOP *before* COLDSTRT which is what confuses me the most, since my reset vector points to COLDSTRT

I thought maybe it was a bad eeprom but replacing that didn't change anything nor did running it from a RAM overlay.

Any ideas what could be behind this weirdness? I will just add a NOP after starting the Timer but really interested to find out wtf is going on
Code:
V_CHARIN:   JMP CHARIN      ; Char in
V_CHAROUT:  JMP CHAROUT     ; Char our
V_CRLF:     JMP CRLF        ; Print CRLF
V_LOAD:     JMP LOAD        ; LOAD (do nothing)
V_SAVE:     JMP SAVE        ; SAVE (do nothing)
V_CLS:      JMP CLS         ; Clear screen
V_HEXTOASC: JMP HEXTOASC    ; HEX byte to Ascii
V_CHARINW:  JMP CHARINW     ; Char in (wait)
V_HEXOUT:   JMP HEXOUT      ; Hex out
V_CHARINU:  JMP CHARINU     ; Char in uppercase
V_FOPEN:    JMP FOPEN
V_FCLOSE:   JMP FDFREE
V_FREAD:    JMP FREAD
V_ERRMSG:   JMP PRERR

COLDSTRT:
            SEI             ;   Disable interrupts
            LDA #<IRQ_ROM
            STA IRQ_softVector
            LDA #>IRQ_ROM
            STA IRQ_softVector+1
            LDX #$FF        ;
            TXS             ;   Init Stack Pointer
            LDX #$00
            STZ SECONDSL
            STZ SECONDSH
            STZ JIFFIES
            STZ INPBUFHEAD
            STZ INPBUFTAIL
            STZ CMDBUFHEAD
            STZ CMDBUFPTR
STACKINIT:  STZ $0100,X
            INX
            BNE STACKINIT

DUARTINIT:  LDA #$B0          ; Reset MRA Pointer to $00
            STA DUARTCRA
            LDA #$C9          ; Enable RX Watchdog, RX Interrupt level 16 bytes, 16 byte FIFO, Baud Extended mode I
            STA DUARTMRA
            LDA #$D3          ; Enable RX controlled RTS, RX Interrupt level 16 bytes, No parity, 8 Bits per character
            STA DUARTMRA
            LDA #$01
            STA DUARTSOPR
            LDA #$07          ; Enable TX CTS Control, 1 Stop Bit
            STA DUARTMRA
            LDA #$60          ; Set timer mode external clock x1
            STA DUARTACR
            LDA #$CC          ; Set TX/RX Baud to 230,400 (115200 with 1.8432Mhz Oscillator)
            STA DUARTCSRA
            LDA #$0A          ; Enable Timer/RxRDYA Interrupts
            STA DUARTIMR
            LDA #$24          ; 100hz interval for Timer
            STA DUARTCTPU
            STZ DUARTCTL
            LDA DUARTSOPR     ; Start timer
            LDA #$05
            STA DUARTCRA      ; Enable TX/RX on Channel A
            LDA #$0A
            STA DUARTCRB      ; Disable TX/RX on Channel B


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 10, 2020 1:10 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
Yes, that does seem somewhat strange. Perhaps you have some odd hardware things going on and the NOP before COLDSTRT allows for some settling time. Do you have any trigger on the NMI line perhaps? On a hardware reset, that might be a problem, but not knowing your hardware, it's just a guess.

Looking at your init code...

I use a SCC2691 UART on my SBC. I also init the counter/timer for a 100Hz jiffyclock. I use $4800 for the init value, while yours in $2400. I looked at the datasheet specifically for that, and the mode you're using looks to be the same as mine (ACR bits 6:4 set to 110), so I would expect your jiffyclock to be 50ms rather than 100ms... unless I'm missing something.

I also use an indexed table to init the UART... but have separate instructions to set the Mode register and it contents. I have two different routines... one does a reset of the UART which is executed first on a coldstart, which ensures the SCC2691 is not in power down mode and also clears everything out. The second is an init routine which sets up all of the operating parameters, enables interrupts for Rx, Tx, Timer, Received Break and starts the timer.

Simple side note... after setting the stack with LDX #$FF, TXS... you can just do an INX which will set the X reg to zero, saves a byte of code vs LDX #$00 ;-)

Can you point to a hardware schematic for your setup?

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 10, 2020 1:23 pm 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
Hi Floobydust

floobydust wrote:
Yes, that does seem somewhat strange. Perhaps you have some odd hardware things going on and the NOP before COLDSTRT allows for some settling time. Do you have any trigger on the NMI line perhaps? On a hardware reset, that might be a problem, but not knowing your hardware, it's just a guess.

NOP Isn't even being executed, I did wonder if somehow thing up above COLDSTRT were being executed so I put a couple of STP opcodes there but they had no effect
I don't have anything connected to NMI besides it's pull-up resistor

Quote:
I use a SCC2691 UART on my SBC. I also init the counter/timer for a 100Hz jiffyclock. I use $4800 for the init value, while yours in $2400. I looked at the datasheet specifically for that, and the mode you're using looks to be the same as mine (ACR bits 6:4 set to 110), so I would expect your jiffyclock to be 50ms rather than 100ms... unless I'm missing something.

I have it set to $2400 because I was too cheap to buy a new oscillator when I switched to the duart, so it's running with a 1.8432Mhz crystal instead of a 3.6864 Mhz Crystal as per the datasheet, I should check how long between reset -> uart init and check that I'm giving the uart enough time to reset - I guess with the halved clock it might take longer

Quote:
Simple side note... after setting the stack with LDX #$FF, TXS... you can just do an INX which will set the X reg to zero, saves a byte of code vs LDX #$00 ;-)

Ah nice!

Quote:
Can you point to a hardware schematic for your setup?

Yep, the Schematics are here the UART is in io.pdf The schematics show the main oscillator as being 5Mhz but I'm running with a 10Mhz can now


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 10, 2020 1:55 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
Quote:
it's running with a 1.8432Mhz crystal

Ah, here we have a clue as to the problem. All the internal functions of the 28L92 are clocked from the UART oscillator. This means they all run slower when you fit a slower crystal. In general, the CPU bus interface is asynchronous to the UART oscillator, so there are synchronising circuits and probably shadow registers.

The practical upshot is that the datasheet specifies a minimum interval between CPU accesses which is dimensioned in UART clocks, not in terms of bus setup and hold times that can be related to the Phi2 clock. If your CPU runs significantly faster than the UART clock, it becomes possible for even a 6502 to outpace this limit with consecutive writes. And I see this in the middle of your code:
Code:
            STA DUARTCTPU
            STZ DUARTCTL


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 10, 2020 2:01 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
Ah, gotcha on the 1.8432MHz clock for the DUART. I also noticed you're configuring the DUART for Motorola mode vs Intel mode. If you think the chip reset timing is slower with the half rate clock, you can just try using a slower CPU clock... as it would be a longer time to get to the DUART init code... something that should be pretty easy to try, e.g., replace the 10MHz can with the 5MHz can.

Beyond this, perhaps a different init routine is in order. You might want to take a look-see at my C02BIOS code (github). I clear page zero first, setup the stack pointer, then initialize a set of software vectors, followed by copying soft init data to page $03, then reset the UART (in software) and the init the UART for operation. I then send a BIOS message out the UART console and jump into the cold start vector for the monitor code.

Finally, any chance you have some noise or ringing on the board with the 10MHz clock?

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 11, 2020 11:06 am 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
Edit: thought I had figured it out but nope... still persists...

However I will definitely follow the advice given, I've ordered a 3.6864MHz can now and will look at your code for a better idea of how to Initialize things

Some other things I found was that I had the issue even at 5MHz, and I could make the issue go away by configuring ca65 to start the code segment at $E001 instead of $E000 which just didn't make any sense at all to me!

I think my 10MHz signal is ok, perhaps the 4-layer PCB saved me here, though there does appear to be some power supply ripple I need to look into

I don't get why moving the code segment from E000 to E001 fixes anything... will have to play around with various offsets I guess


Attachments:
File comment: Power ripple
DS1Z_QuickPrint6.png
DS1Z_QuickPrint6.png [ 48.12 KiB | Viewed 742 times ]
File comment: 10MHz Clock
DS1Z_QuickPrint5.png
DS1Z_QuickPrint5.png [ 30.06 KiB | Viewed 742 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 11, 2020 11:49 am 
Offline
User avatar

Joined: Sun Dec 29, 2002 8:56 pm
Posts: 460
Location: Canada
Is address line a0 connected correctly? Since things seems to be affected by changing the address by one.

_________________
http://www.finitron.ca


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 11, 2020 11:54 am 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
I think I've figured it out now, since I'm using it in Motorola mode (i.e R/W rather than RDN and WRN) I need to qualify /CS by PHI2 because otherwise garbage is probably getting written to the registers. I had tried this earlier and it didn't fix anything but it turns out Quartus was programming the output of a different copy of the glue code...
After adding "AND PHI2='1'" to the equation for the chip select it now seems to work fine


Last edited by LIV2 on Sat Jul 11, 2020 12:47 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 11, 2020 12:44 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
Glad that you figured it out... I've not used the Motorola mode, then again the older SCC2691 doesn't offer it. I do have some of the newer NXP DUARTs (including the SC28L92) which I'll be using on the next SBC. I'll be using Intel mode, as I already have a TL7705B Reset chip on my current design (has both positive and negative reset outputs) and the glue logic is already done and has Ph2 qualified read and write signals.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 11, 2020 12:52 pm 
Offline

Joined: Wed Feb 12, 2014 1:39 am
Posts: 173
Location: Sweden
Maybe I should've gone down that route in the first place, what made me think it was super strange is that this has worked fine for a couple of years now until the other day when I started shuffling bits of my rom code around.

Thanks for your help now I need to have a look at your code for some inspiration :)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: