View unanswered posts | View active topics It is currently Fri Mar 29, 2024 11:18 am



Reply to topic  [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
 Started 6809 core 
Author Message

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Added BCD arithmetic to the 6809 core. There is a decimal mode flag in the condition code register now that when set switches some arithmetic operation to decimal mode. (ADD, ADC, SUB, SBC, NEG, and MUL). Only A,B, and D accumulator instructions are affected. The other registers do not support decimal mode. It takes an extra clock cycle for immediate mode operations to perform decimal arithmetic. BCD multiply is given 17 clocks to complete.

Modified the interrupt structure to make better use of the three interrupt inputs. They may now work like 68000 interrupt inputs. An extra mask bit in the ccr was needed to implement this. A value encoded onto nmi, firq, and irq generates an interrupt at that level. to generate a nmi for instance all three interrupt lines would need to be activated. However, the interrupts can still be made to look like the existing system by careful use of vectors.

The mode register of the 6309 is now supported. It controls register stacking for the FIRQ interrupt input. It also has a new bit in it to set the operation of the interrupt lines. Unlike the 6309 the low order mode bits can be tested with the BITMD instruction.

Got the first working sample of a hardware breakpoint. Set a hardware breakpoint in a multiply test routine and it worked.
Wrote a routine to test multiply performance but forgot that the performance would be limited by cache loads. I was able to time a MULD instruction in ILA and it looks to be 12 clock cycles.

_________________
Robert Finch http://www.finitron.ca


Sat Feb 05, 2022 5:18 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Changed the way interrupt vectoring works slightly. Interrupt vectors are now space four bytes apart instead of two to accommodate a three-byte address. The extra fourth byte is for convenience and future use. It allows vectors to be defined as ‘fcdw’.

Added a simple MMU to the system. Its along the lines of the 6829 MMU but a bit simpler although handling more memory pages and more tasks. The MMU maps only a 24-bit virtual address instead of the full 36-bit available. The 24-bit virtual address is mapped into a 32-bit physical address space. All devices on the system side of the MMU are mapped. That includes all I/O including the MMU itself. So, once it is setup it should be mapped into the address space, or it will not be possible to change mappings.

Working on spacing the I/O devices out at 8kB intervals. That happens to be the size of a MMU page.

Found a trick with having I/O memory mapped. To access an I/O device it is simply temporarily mapped to a base address of zero. Then direct page can be used to access the I/O registers. Mapping an address is fast. It is simply a matter of updating a couple of bytes in the mapping table. It can be done fast enough to take place during interrupt processing code.

I have been working away on the 12-bit version of the core, for the most part ignoring the 8-bit version. So, I am not sure the 8-bit version still works.

_________________
Robert Finch http://www.finitron.ca


Sun Feb 06, 2022 3:57 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Got interrupt driven serial receive working, the phantom carriage returns appear to be gone. I re-wrote part of the serial and timer routines to operate using the MMU, and I must have fixed something in the process.

The system runs noticeably slower with the MMU logic in place. The MMU adds two clock cycles for address translation to every memory access.

I have been documenting the inner workings of the Femtiki operating system while waiting for system builds. I hope to have an OS kernel working at some point. I have had this OS partially working on a couple of systems now so there is code to port.

_________________
Robert Finch http://www.finitron.ca


Mon Feb 07, 2022 5:23 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Working on memory management routines. I had this wonderful code to test, set, clear, and get individual bits from a page allocation map that was bitmap based. Then I realized that there was duplication of values because a share count is also maintained for each page of memory. The share count is a single byte, not a bit. The share count can also serve to indicate if memory is allocated. So, the bit routines got scrapped.

_________________
Robert Finch http://www.finitron.ca


Tue Feb 08, 2022 6:43 am
Profile WWW

Joined: Mon Oct 07, 2019 2:41 am
Posts: 585
Do you have any way of keeping free blocks around the top of the stack for a push or a pop,
when you have code in a critical section?


Tue Feb 08, 2022 2:44 pm
Profile

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Been working on the OS some more.
Quote:
Do you have any way of keeping free blocks around the top of the stack for a push or a pop,
when you have code in a critical section?

Memory is allocated by the OS in 8kB pages. The stack is allocated at the top of the virtual address space and potentially grows downwards. Since the stack is quite large it is not likely to overflow. There is currently no protection for critical sections. I have not got as far as writing things like heap managers yet. I am just working on the OS / BIOS memory routines. The heap manager will manage memory with a lot finer grain than the OS.

The system supports 32 memory maps, one for each possible active app in the system. I figured 32 was loads of apps to be running in a small system. Just looking at my windows machine ATM there are only eight apps running with about 3000 threads. The stack area is associated with a memory map. There can be up to 4095 tasks in the system. Stack space for the tasks will need to be allocated from the stack area of the app. So, stacks might need to grow downwards if there are a lot of tasks running. (A task is a thread.) ATM the OS is chewing up about 2MB of overhead to manage OS objects. There are a lot of objects. Most things are statically allocated for simplicity.

Apps (ACBs) 32 (16kB each)
Tasks (TCBs) 4095 (192B each)
Messages (MSGs) 21842 (12B each)
Mailboxes (MBXs) 9762 (10B each)

There is one mailbox per task / thread plus some extras.

_________________
Robert Finch http://www.finitron.ca


Thu Feb 10, 2022 1:38 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Got a bunch of yellow squares showing up on the screen, that had me going for a moment. Then I realized it was the software activated flashing cursor, which was not clearing its old location properly, so it left trails. The software cursor flash was not previously working so never showed on-screen, but now it works.

My latest trial has been to get the OS timer routine into the picture. The timer routine is called via a SWI2 call and saves state in the TCB. Returning from the SWI call restores state from the TCB. I figure if things can be made to work for a single thread then getting things to work with multiple threads will follow.

_________________
Robert Finch http://www.finitron.ca


Fri Feb 11, 2022 6:06 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Moved the memory allocation functions to the BIOS. I had placed them in the OS but really allocating memory could be done by any OS. Memory allocation may be needed by other software. There is no reason to restrict it to Femtiki.

Spent some time fixing up the assembler. It is very good, but it had some annoying characteristics. Pseudo-ops could not be used at the first character of a line because they would then be interpreted as a label. The “TAB” instruction conflicted with an equate for the tab character. Since I do not know of a TAB instruction as part of the 6809 instruction-set, I simply disabled it. I am working on getting the assembler so that it can assemble the output of the VBCC compiler.

Interrupts were not properly masked on reset. I added another interrupt mask flag to the core but then forgot to set it during reset. This led to interrupts occurring before the system was fully setup, resulting in a crash.

_________________
Robert Finch http://www.finitron.ca


Sat Feb 12, 2022 3:49 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Latest Fixes:
The SWI instruction was masking interrupts before the CCR got saved. This led to interrupts being masked on return from interrupt (RTI).
The 6309 similar AIM, TIM, OIM, EIM instructions were not taking the position of the immediate byte into consideration during decoding. This led to these instructions being improperly decoded and not working correctly.

Latest Additions:
Added the JTT – jump to task instruction and a task register TR. The JTT instruction loads the context from the task control block specified in the TR. The JTT instruction first loads the TR with the effective address specified, then performs the context load operation. The SWI2 instruction was modified to look at the task register and if the TR is non-zero then the SWI2 instruction stores the context of the currently running task in the TCB instead of stacking the registers on the stack. The TR is write-only and can be set back to zero by specifying zero as the address in the JTT instruction, in which case the context will not be loaded. This means a TCB cannot be located at address zero. At reset the TR is set to zero so SWI2 performs normally.

_________________
Robert Finch http://www.finitron.ca


Sun Feb 13, 2022 3:36 am
Profile WWW

Joined: Sun Dec 20, 2020 1:54 pm
Posts: 74
@robfinch
There is Gcc *unofficial* support.
- it's a fork maintained by a single dude
- it's somehow working for basic stuff
- it only supports C, there is no stable C++ support

I played with it years ago, then I moved on other things :D


Sun Feb 13, 2022 1:31 pm
Profile

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Got to wondering why access to dram was so slow. The memory controller was timing out after 512 clock cycles. So, a dram access was taking 512 clock cycles. I built the safety timeout in to prevent the whole system from locking up if there was some sort of hardware issue.

I found one issue with the controller almost immediately. It was invalidating cache lines in the read caches improperly. The invalidate signal was generated from only the app_cmd signal being CMD_WRITE. But this is the default case, even when there is no activity. So, invalidates where happening on virtually every memory access. The signal needed to be further qualified for write cycles only.

Issue with the multi-port memory controller today. Exactly when it sends back an ack signal and when it cancels the ack. It appears to be reading memory over and over again without generating an ack.
The controller is now responding in acceptable time, however, the data is not correct. Added a bunch of signals in ILA to debug the thing.

_________________
Robert Finch http://www.finitron.ca


Mon Feb 14, 2022 4:34 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Really worked on the memory controller today. Broke it up into a number of smaller modules. Still more work to go.

Re-wrote the read cache portion. There is just a single cache now with 8 read ports instead of 8 separate caches. The size of the cache was set to 16kB.

_________________
Robert Finch http://www.finitron.ca


Tue Feb 15, 2022 5:37 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Using a hybrid approach now. Added streaming read caches for streamed data to the memory controller. The issue is that streamed data like frame buffer reads, sprite data reads, or audio data reads would pollute the main cache with data making it necessary to reload most of the cache all the time. The streaming caches are small (16 lines) because the data is going to be overwritten anyway.

Did it again. Coded initialization routines to clear out the TCB and it should not be cleared out. The register set of the TCB is set by the call to the OS initialization routine. Without the registers being valid there is no way for the code to return to the correct address.

Forgot to initialize the stack pointer value in the TCB. This caused the vectors to be overwritten as stack pushes began decrementing from zero around to the top of the address space. This took a while to figure out. Eventually found using multiple comparators and address matching in the ILA.

Finally got things back to almost working this time using the JTT Jump to Task instruction and SWI2 handling of tasks. The SWI2 routine exits now using a JTT back to the selected task rather than an RTI instruction. Displays the boot screen but interrupts are not working. Suspect they are being disabled by the new task switching code.

_________________
Robert Finch http://www.finitron.ca


Wed Feb 16, 2022 4:05 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
JTT loads all the register from the TCB including the direct page register which was not being set in the TCB. So direct page was set to an essentially random value.
Got interrupts working again now having fixed the direct page issue.

Milestone: Today is the first time the system has got to the Femtiki timer routine and back again without crashing.

Now I got it as far a selecting a task from the ready queue. There is only one task in the queue to select from, but it seems to work.

Now that I got it all working I decided to change things a little bit. Returned the SWI2 instruction to its normal operation and added another instruction ‘SYS’ that uses TCBs. Modified the task register so that it just holds the task handle rather than the TCB address. Modified the size of TCBs to be 256 bytes from 192 bytes to make address calculations simpler. The new SYS instruction calculates the address of the TCB from the TR and a TCB base address register, to determine where to store the context info. The JTT instruction no longer loads the TR. The TR must be set by other code. The TR can be used in the TFR and EXG instructions.

_________________
Robert Finch http://www.finitron.ca


Thu Feb 17, 2022 4:59 am
Profile WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Backing up a little bit. The timer IRQ going through Femtiki no longer works. It appears that timer routine is not reading correct data for the thread. Because the data is incorrect the wrong OS routine is called. It appears to be reading all zeros for the data. So, I rebuild the system without the Femtiki timer routine and tested it out. I can dump and edit and fill memory successfully. I do not think it is the memory controller causing the issue. So, more debugging is needed.

_________________
Robert Finch http://www.finitron.ca


Fri Feb 18, 2022 4:21 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

Who is online

Users browsing this forum: SemrushBot and 25 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:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software