danwinslow Posted January 3, 2016 Share Posted January 3, 2016 (edited) Hi all - I'm starting to look at storing something under the OS. One slight difference from a lot of what I'm finding on the subject is that I *only* will be accessing it in a VB...both immediate and deferred. I think that actually makes it easier, but I'm not sure. I have some questions : 1. Am I right in saying that accessing only during VB will make it easier? I'm thinking I won't have to worry about VB's and DLI's. 2. What will I lose in terms of being able to run on various setups? I would like this to be as generally usable as possible. 3. What is the 'unused' portion between C000-D000. Is that really inaccessible? Edited January 4, 2016 by danwinslow Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 4, 2016 Author Share Posted January 4, 2016 nm, I found an old post of mine asking basically the same question. Still am unsure about the C000-CFFF area, why is that referred to as 'unused' in some diagrams? Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 4, 2016 Share Posted January 4, 2016 1. "Easier" - sort of. Stage 1 VB you don't have the risk of any other interrupts that the OS is absent to handle. Stage 2 though, the OS isn't there to handle interrupts (IRQs will be enabled) so you have potential for trouble. Stage 2 VB you don't have guarantee that it always occurs so think twice before using it anyway. Also a very long Stage 2 could potentially be interrupted by DLIs if the active display starts again. Workaround for Stage 2 potential problems could be just do a SEI before swapping out the OS, CLI once the Rom is back in. There's potential for real problems if SIO is going on but just avoid doing any such thing while your routine is active. 2. Numerous Doses use the Ram under the OS. There's a patch for 2.5 that keeps Dup.sys and Mem.sav there. SpartaDos can be setup to enable using that memory. In general it's not easy to find out if something is already using that memory, you have to rely on the user to know well enough not to create a clash situation. 3. $C000-$CFFF - It was "unused" on the factory memory map of 400/800. Early Ram expansions sometimes used it for Ram. Modified OSes with Monitors generally used it to hold the monitor code. The XL/later OS uses it, as such there is 14K which is swapped out in one hit if you disable the OS via PORTB setting. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 4, 2016 Author Share Posted January 4, 2016 (edited) 14k, wow. Yes, I was testing and the $C000 range does seem to be usable. Stage 2, with and without CIO running, works well with my stuff so far, although any kind of game that relies on heavy VB work won't be compatible. I hadn't thought about DLI's on overrun though, I'll have to test that. Edited January 4, 2016 by danwinslow Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 4, 2016 Share Posted January 4, 2016 You could handle NMIs yourself. They're easy since only 2 types. IRQs are totally different though. There's multiple sources and PBI devices can generate them too. Best bet with IRQs is to just disable via SEI for the duration. Don't confuse CIO with SIO. CIO doesn't use interrupts so is mostly irrelevant. But like I said before, using Stage 2 VB has no guarantees. All it takes is a keypress at the right time and it will be bypassed. Or disk IO taking place in which case almost all will be skipped. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted January 4, 2016 Share Posted January 4, 2016 why not going the full mile and disable OS completly (except you need OS routines like text CIO etc). that's what I am doing since for ages. the 14k extra memory is a bonus why not use it? I mainly put there unrolled code or data/videoram/player missle stuff... fex. $dc00-$dfff for players, $e000- ... for double buffering video ram. $c000 for 4k lookup tables etc. 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 4, 2016 Share Posted January 4, 2016 If you're doing stuff for Basic or need OS services then you generally want to keep the OS around. Another thing I should mention. It's not good for your Stage 1 VB to go too long (the docs mention it). If you delay things too much, SIO will stop working properly, and screen corruption can occur if the shadow register copies are delayed too much... the problem there is that the DList pointer if reloaded during active display will restart the screen with 24 extra blank scanlines. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 4, 2016 Author Share Posted January 4, 2016 Yes, that's the idea, I want the driver to be able to co-exist with as much normal programming stuff as possible, otherwise I surely would just punt the OS entirely. So far it works perfectly with SIO, and missing a few deferred stage 2's is no problem. But, sadly, I'm starting to run out of room in the single extended bank I'm using. Right now I have 4k of non-banked used by the CIO handler, which leaves BASIC with around 29k of usable space. I have about 2.8 k of space left in the single extended bank. The 4k for the handler is mostly buffer space, because the IO runs in the extended bank and it's handy to be able to have the buffers in real memory shared by the handler. It lets me dump bytes to the handler memory, directly accessible to user programs and skip the laborious extra copies from extended. But I'd like to minimize the handler memory, leaving as much space as possible for user programs. I also don't know if the second half of the TCP code I have yet to write will fit into the extended bank. I'd like to get the handler usage down to 2k or less, and be able to fit the rest of the TCP code into the single extended bank. Careful use of the RAM under the OS would really help, as long as it wouldn't disturb things too much. I could just go ahead and use another extended bank, but as I said it introduces some issues with buffer copying speed. Stage 1 all I do is increment some internal timers. Stage 2 is where the actual work happens, and missing up to 50% of them if IO is running doesn't seem to disturb much. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted January 4, 2016 Share Posted January 4, 2016 aah. so no game then... if it's an app... go for OS friendly - as much as you can Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 5, 2016 Share Posted January 5, 2016 Yep, driver and play well with Doses and applications, tricky stuff. A worthwhile strategy might be to write it such that you can easily have multiple versions which use different parts of memory to suit the environment. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 5, 2016 Author Share Posted January 5, 2016 Yes, that's an excellent suggestion, was thinking the same. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 10, 2016 Author Share Posted January 10, 2016 (edited) So, I've been looking at this code, as a means to enable IRQ and NMI protection when the OS is swapped out. Can anyone explain what the deal with the DFB $24 is? Is that just a fancy way of skipping the CLC if it's entered at the NMI address, or is there something else going on there? Wouldn't a BCS accomplish the same thing? NMI SEC ;Set carry-flag, and DFB $24 ;skip the next byte ;(BIT has opcode $24) IRQ CLC ;Clear carry-flag PHA ;Save A and X, and TXA ;copy the stack TSX ;pointer into X PHA LDA $D301 ;Swith the ROM on, PHA ;and save the old ORA #1 ;value STA $D301 LDA #BACK:H ;Set the adress PHA ;where RTI will LDA #BACK:L ;jump PHA INX ;Transfer state INX ;of flags before LDA $100,X ;interrupt PHA BCC IRQJUMP ;Which interrupt? JMP ($FFFA) ;Run NMI in ROM! IRQJUMP JMP ($FFFE) ;Run IRQ in ROM! ;When the routine in ROM ;finished its work: BACK PLA ;Return ROM into STA $D301 ;original state PLA ;End of interrupt! TAX PLA RTI Note that we need to initialize it first - in this way: INIT LDA #0 ;Disable all the STA $D40E ;interrupts SEI LDA #$FE ;ROM OFF! STA $D301 LDA #NMI:L ;Set NMI adress! STA $FFFA LDA #NMI:H STA $FFFB LDA #IRQ:L ;Set IRQ adress! STA $FFFE LDA #IRQ:H STA $FFFF INC $D301 ;ROM ON! CLI ;Enable interrupts LDA #$40 STA $D40E RTS ;That's all! Edited January 10, 2016 by danwinslow Quote Link to comment Share on other sites More sharing options...
MrMartian Posted January 10, 2016 Share Posted January 10, 2016 Yes, as you say it's a fancy way of skipping the CLC. If you enter at NMI, you get SEC, BIT $18, PHA ... etc.. IRQ gets you CLC, PHA, etc... Skips the instruction without a jump. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 10, 2016 Author Share Posted January 10, 2016 (edited) I'm assuming there's no issue with replacing it with a bcs. Edited January 10, 2016 by danwinslow Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 10, 2016 Share Posted January 10, 2016 (edited) The techique of using that BIT as a sort of NOP/skip next instruction is a memory and cycle saving exercise. Yes, it makes the program harder to understand. The sort of interrupt handling being done here can have problems. It'll add way too much overhead to practically any DLI. For IRQs it should be OK but SIO at anything over stock speeds might have trouble. Personally, I'd probably just use the Immediate VBlank, leave IRQs masked while the OS is swapped out. Do the shadow register copy stuff that the OS Stage 2 VBlank would otherwise have done. Then return with the OS swapped back in, ie JMP $E462. The thing to be careful of though is don't let the routine run into normal display time. Alternatively, handle the NMI case differently. DLIs generally won't have dependancy on the OS Rom being present. Though if you're doing a driver or some program that's in an otherwise unknown environment, e.g. might execute with a word processor loaded or something - then you can't depend on that being the case. Edited January 10, 2016 by Rybags Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 10, 2016 Author Share Posted January 10, 2016 (edited) Yeah, it's not looking like this is going to work out very well. Since I want to support at least some DLI activity, I really can't swap the OS much if I'm not in the VB, plus Sparta and RealDos both steal those vectors themselves and put code under the OS, so it's probably not practical anyway. I really need about 4k more buffer space though. I can probably move it into another ext bank but that leads to unfortunate amounts of copying. Maybe I can put the buffers in low mem and move the actual CIO device handler into another bank. It's important to be able to write the packet directly into the user space, which means the driver needs to write the buffers in a spot that can be directly accessible to user code that probably will be in the bank window. Learned some stuff from looking at that code, though, it's pretty cool. Edited January 10, 2016 by danwinslow Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 10, 2016 Share Posted January 10, 2016 You could just do a proper NMI handler in Ram. The critical thing though is that any DLI would have to not need the OS Rom in place. Generally that's the case anyway. The other thing, probably already covered - in the active display it's probably a good idea to have an exact copy of the character set in Ram at $E000 Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 10, 2016 Author Share Posted January 10, 2016 You know, on top of fit all, this code I used just doesn't seem right. The sequence followed when an IRQ occurs screws up the stack. The first RTI does not return whence it came from. It goes off somewhere else in the rom and eventually RTS's, but the stack is screwed up so I wind up jumping right in the middle of some unrelated code and crashing. I think they are trying to jimmy the stack to get the RTI come back to the intercept routine right after the indirect JMP, but it's not doing it right. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 10, 2016 Share Posted January 10, 2016 Is there any special reason that driver code has to run in the NMI? SpartaDOS X can use main memory, OS RAM and extended RAM for disk buffers, but there isn't this additional complexity of actually accessing the shadow RAM from inside of interrupts. It sounds like things are becoming rather complicated. Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 10, 2016 Author Share Posted January 10, 2016 Looks like the issue with code may be an OS version thing...the ROM IRQ I have is pulling the y,x, and a regs off before doing the RTI, and they did not allow for that. FJC : not really, but if the driver is to stay 'running' while no program is executing it needs a interrupt thread so it can poll for packets, answer pings, etc., as in a regular ethernet stack. Plus it allows user programs, such as BASIC, to not have to worry about continuously calling some 'poll()' routine. I do plan a version of the stack that would be linked into a user program, and that program would have the responsibility to call it often enough. I don't think the problem, at least right now, is that I'm in a VB at the time, its that the code I copied from (above) is either bad or at least out of date from my ROM. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 10, 2016 Share Posted January 10, 2016 OK - thanks. Makes sense now. Sounds like a great application for a multi-processing environment where the Ethernet driver can run as a service. 1 Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 10, 2016 Author Share Posted January 10, 2016 yes! the 'service' in this case is the CIO handler connected to the driver, which makes all the user programming easy. It works well, I'm just out of room and trying to find some more without intrducing a lot of copying. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 10, 2016 Share Posted January 10, 2016 It would (will) be much easier in a multi-tasking OS environment, though, since you can put your polling routine on a timer and not worry about upsetting other interrupts (since you're essentially still in mainline code). Quote Link to comment Share on other sites More sharing options...
danwinslow Posted January 10, 2016 Author Share Posted January 10, 2016 yes, I'm waiting for something exactly like that. Hmmm. Who do I know doing something like that? Hmmm. 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 10, 2016 Share Posted January 10, 2016 Yeah... as soon as he can get untangled from firmware. 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.