tschak909 Posted July 20, 2014 Share Posted July 20, 2014 Just the right amount of ambition and sheer persistence. This thread puts a serious smile on my face. -Thom 1 Quote Link to comment Share on other sites More sharing options...
Prodatron Posted July 20, 2014 Share Posted July 20, 2014 My 6502 skills are still very limited, but this code looks really fast and compact! I suppose messages intended for more than one recipient will have to be instanced multiple times, because messages without a specific addressee just don't fit this scheme at all. Still don't know what SymbOS does with those. There is no support for broadcast messages in SymbOS. I wonder in which cases this would be helpful? As you ask I guess this is a feature of other multitasking operating systems, so I would like to know, why they need that. Wouldn't it also be necessary to introduce different process groups? E.g. there are system and application processes. At the moment I can only think about a very few system events, where you could need broadcast messages ("system shuts down", "screensaver starts" [but even for the latter one it's not required in SymbOS]). I guess I would just send multiple copies of the messages for such cases. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 20, 2014 Author Share Posted July 20, 2014 (edited) It was the SymbOS developer docs which seemed to indicate that broadcast messages are possible. I'm sure one can set the PID to 'any' when sending and receiving messages? Perhaps with $FF. In any case, if you don't handle it, my mind is put at ease. I also thought the receiver could specify that it only wanted to receive a message from a specific process; this would slightly complicate things, but perhaps that's not the case either, and the receiver must simply react to the sender ID of the incoming message. Edited July 20, 2014 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
Prodatron Posted July 20, 2014 Share Posted July 20, 2014 (edited) It was the SymbOS developer docs which seemed to indicate that broadcast messages are possible. I'm sure one can set the PID to 'any' when sending and receiving messages? Perhaps with $FF. In any case, if you don't handle it, my mind is put at ease. I also thought the receiver could specify that it only wanted to receive a message from a specific process; this would slightly complicate things, but perhaps that's not the case either, and the receiver must simply react to the sender ID of the incoming message. Yeah, it was receiving messages from any process (ID = -1), not sending to any process! So yes, you can send a message only to one process. But when you listen for new messages, you can specify the sender or just watch out for any message of any other process. As an example that makes sense if you currently only want to communicate with one other process (e.g. the Desktop Manager), telling him to open a window, receiving the window ID etc. In this part of the code you don't want to take care about other messages, which could occur as well because we are in a multitasking environment. In your "main loop" you want to check all messages, but in special situations, where you only want to communicate with one specific process you want to ignore all other ones. They stay untouched in the queue and can be received later. Edited July 20, 2014 by Prodatron 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 20, 2014 Author Share Posted July 20, 2014 In your "main loop" you want to check all messages, but in special situations, where you only want to communicate with one specific process you want to ignore all other ones. They stay untouched in the queue and can be received later. Right: so if we're filtering the messages by sender, we can only update the 'first message' pointer if the message received is the first one in the 'sub-list'. A few extra lines of code will handle that. Quote Link to comment Share on other sites More sharing options...
Prodatron Posted July 21, 2014 Share Posted July 21, 2014 Oh yes, that's right, I forgot to mention it before Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 25, 2014 Author Share Posted July 25, 2014 (edited) How about having a pool of, say, 16-32 page zero locations. A process gets assigned exactly as many locations as it requests after loading and during relocation. Only swap out zp locations if the pool runs dry. +1. I think you were the first to suggest this and it turned out to be the best solution once I figured out how to perform the relocation. Coupled with stack segmentation and fall-back stack caching (when we run out of stack slots), this kind of page zero allocation (coupled also with fall-back caching if the pool is exhausted) means a context switch can potentially take place with no copying loops whatsoever, even if the application has a half-full stack and a number of ZP locations. Thus the two major drawbacks of the 6502 are overcome. Edited July 25, 2014 by flashjazzcat 2 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 28, 2014 Author Share Posted July 28, 2014 After many hours of pure slog, I've ironed out the banking bugs in the first cart build, and suddenly it gets as far as relocating the kernel into RAM and starting up the scheduler. The inter-bank JSR mechanism seems to work just great, although cartridge debugging (and this is my first real attempt at it) is a total nightmare. Anyway: thanks to Jac! and MrFish for keeping morale high. I'll try to get the UI manager and the desktop running concurrently and then I'll have to ease off for a while (I'm spending far too much time on this thing, much to my wife's consternation). 2 Quote Link to comment Share on other sites More sharing options...
tschak909 Posted July 28, 2014 Share Posted July 28, 2014 I can completely relate. When I told my wife that I was writing a BBS package for a 30 year old computer, she gave me a confused look, when I told her I am writing it to clear my head (mental cucumber), she just shook her head and walked away. -Thom 2 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 28, 2014 Author Share Posted July 28, 2014 See what she says three and a half years later if it's still not finished and you look visibly aged. 5 Quote Link to comment Share on other sites More sharing options...
Wiffleplop Posted July 29, 2014 Share Posted July 29, 2014 Well I think you're looking younger, if anything Please do keep the faith though, as you'll be making a lot of A8 users very happy when you're done. Then if you could fix windows 8, that'd be cool Quote Link to comment Share on other sites More sharing options...
Chilly Willy Posted July 29, 2014 Share Posted July 29, 2014 After many hours of pure slog, I've ironed out the banking bugs in the first cart build, and suddenly it gets as far as relocating the kernel into RAM and starting up the scheduler. The inter-bank JSR mechanism seems to work just great, although cartridge debugging (and this is my first real attempt at it) is a total nightmare. Anyway: thanks to Jac! and MrFish for keeping morale high. I'll try to get the UI manager and the desktop running concurrently and then I'll have to ease off for a while (I'm spending far too much time on this thing, much to my wife's consternation). Sounds good! I still hold out hope to being able to use my 65XE with the AtariMax Flash cart. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 29, 2014 Author Share Posted July 29, 2014 Sounds good! I still hold out hope to being able to use my 65XE with the AtariMax Flash cart. Providing you only want to run one tiny application at a time, this should be possible. Quote Link to comment Share on other sites More sharing options...
Chilly Willy Posted July 30, 2014 Share Posted July 30, 2014 Providing you only want to run one tiny application at a time, this should be possible. I'll take what I can get. I wasn't planning on doing a lot of multitasking on it. That will have to wait until I can get a memory expansion... maybe a 130XE as well. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 30, 2014 Author Share Posted July 30, 2014 Who needs screenshots when you have Altirra's execution history: 1 Quote Link to comment Share on other sites More sharing options...
ivop Posted July 30, 2014 Share Posted July 30, 2014 +1. I think you were the first to suggest this and it turned out to be the best solution once I figured out how to perform the relocation. Coupled with stack segmentation and fall-back stack caching (when we run out of stack slots), this kind of page zero allocation (coupled also with fall-back caching if the pool is exhausted) means a context switch can potentially take place with no copying loops whatsoever, even if the application has a half-full stack and a number of ZP locations. Thus the two major drawbacks of the 6502 are overcome. Thanks. Glad you figured out a way to get it working in your setup. It was actually based on an idea I had years ago when I was thinking about multitasking on a 6502. Never got around to actually code something though. Looking forward to see your implementation running Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted July 31, 2014 Share Posted July 31, 2014 I can completely relate. When I told my wife that I was writing a BBS package for a 30 year old computer, she gave me a confused look, when I told her I am writing it to clear my head (mental cucumber), she just shook her head and walked away. -Thom This is off-topic, so I'll keep it short, but please be sure to keep us informed (in a separate thread) of your progress on the BBS program. I am very interested in it, and, I'm sure others are, as well. -K Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted July 31, 2014 Author Share Posted July 31, 2014 This is off-topic, so I'll keep it short, but please be sure to keep us informed (in a separate thread) of your progress on the BBS program. Try this topic: http://atariage.com/forums/topic/228134-new-atari-bbs-software/ Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted July 31, 2014 Share Posted July 31, 2014 Try this topic: http://atariage.com/forums/topic/228134-new-atari-bbs-software/ Thanks Jon Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 1, 2014 Author Share Posted August 1, 2014 (edited) Ouch: testing the kernel in Altirra, I discovered that on entering the IRQ handler via BRK, occasionally a Pokey timer interrupt request bit is already set, causing the ISR to acknowledge and service the timer interrupt and miss BRK entirely. I'm not sure why the Pokey interrupt request would fail to pre-empt the software interrupt, unless this is another 6502 quirk. I thought it was only NMIs which could cause BRK to be missed (by entering the NMI handler with the BRK flag set; this condition is already handled). The slightly inconvenient fix is to test for BRK before testing bits in IRQST, although I'm still quite surprised by the apparent behaviour which necessitates this. Edited August 1, 2014 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
+JAC! Posted August 1, 2014 Share Posted August 1, 2014 (edited) I think this in the nature of the BRK instruction. As with any other IRQ interrupt can occur at the same cycle (SERIN, SEROU, KEY, ..) you have to check the correspond bit in the interrupt status registers (IRQST is just one of them, there could be any other part in the HW/PBI triggering an IRQ) to find out which IRQ sources are active and which if them has to be served first. The "quirk" is that the B-flag is just a status bit and does not actually trigger the interrupt, nor does it have an explicit clear instruction. It is automatically "cleared" by RTI. Hence checking for the B-flag in the main IRQ handler is correct and the only solution from my point of view. Edited August 1, 2014 by JAC! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 1, 2014 Author Share Posted August 1, 2014 Makes sense I suppose. Syscall is the only interrupt we mustn't miss under any circumstance, so we must check for BRK first. Takes the shine off using BRK a bit, but we'll see how it goes. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 1, 2014 Author Share Posted August 1, 2014 (edited) Hasn't really spoiled the party. The interrupt handlers - being freed from the stock OS and thus not generic - are still pretty lean even with all the checks, although that Pokey timer 2 is taking quite a hit (it runs at 800Hz): .proc IRQHand pha txa pha cld tsx lda $103,x and #$10 ; check for brk flag first since it's critical we don't miss it bne SupervisorCall lda #2 bit irqst ; Pokey Timer 2 bne NotTimer2 lda #4 sta irqen lda #6 sta irqen jmp Mouse NotTimer2 lda #4 bit irqst ; Pokey Timer 4 bne NotTimer4 lda #2 sta irqen lda #6 sta irqen jmp Scheduler NotTimer4 pla tax pla rti SupervisorCall ... .endp .proc NMIHand pha txa pha tya pha cld bit nmist bpl NotDLI jmp Draw_Mouse NotDLI sta nmires jmp VBI .endp .proc ExitNMI tsx lda $0104,x ; get saved processor status register and #$10 ; check for BRK flag beq NotBRK lda $0105,x sec sbc #2 ; drop PC by 2 (back to missed BRK) sta $0105,x lda $0106,x sbc #0 sta $0106,x ; RTI will immediately return to BRK instruction NotBRK pla tay pla tax pla rti .endp Edited August 1, 2014 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
+JAC! Posted August 1, 2014 Share Posted August 1, 2014 (edited) I think there's still a gap. If the NMIHand occurs when IRQHand just starts, it'll assume that it can re-execute the BRK in ExitNMI. But BRK will not be the last instruction in the actual sequence. And the only way to prevent this I can think of would be prefixing every BRK with an explicit SEI to ensure the situation does not occur. And then a JSR <fixed_kernel_entry+3*command> looks not that bad again. Edited August 1, 2014 by JAC! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 2, 2014 Author Share Posted August 2, 2014 (edited) I cannot visualise this scenario. IRQ pushes B=0, so even if NMI fired simultaneously, how does the NMI exit see a BRK which isn't there? Sorry if I'm being dense... so tired. Oh - assuming it's not in vain, this reduces latency somewhat: .proc IRQHand sta IRQSaveA pla ; get flags pha and #$10 ; check for brk flag first since it's critical we don't miss it bne SupervisorCall lda #2 bit irqst ; Pokey Timer 2 bne NotTimer2 lda #4 sta irqen lda #6 sta irqen jmp Mouse NotTimer2 lda #4 bit irqst ; Pokey Timer 4 bne NotTimer4 lda #2 sta irqen lda #6 sta irqen jmp Scheduler NotTimer4 lda IRQSaveA rti SupervisorCall ... .endp Timer 2 doesn't use the X register unless the mouse has moved, so getting rid of the indexed addressing at the top of the ISR saves pointlessly saving X when it's not necessarily needed. CLD can also be skipped when the mouse is idle. Edited August 2, 2014 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.