Asmusr Posted March 22 Share Posted March 22 Maybe some of the confusion about whether you should write the same value to both the MSB and the LSB of a SAMs register is because when you read the value back - even if you have only written to the MSB - both MSB and LSB contain the same value. That's at least how it is in MAME according to the debugger. Classic 99 doesn't seem to let you read the register values back at all, again according to the debugger. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 22 Share Posted March 22 21 minutes ago, Asmusr said: Classic 99 doesn't seem to let you read the register values back at all, again according to the debugger. As I last posted, I did read back a SAMS register via MOV and received the page# in the MSB and the bank# in the LSB. The Classic99 debugger did not complain to me. My fbForth assembler code is HEX ASM: SAMSRD ( reg -- val ) *SP R1 MOV, \ get SAMS register# (0..Fh) from stack R1 1 SLA, \ *2 (SAMS regs on even address boundaries) R1 4000 AI, \ compute SAMS register address R12 1E00 LI, \ load CRU of SAMS card 0 SBO, \ turn on SAMS card *R1 *SP MOV, \ read SAMS register 0 SBZ, \ turn off SAMS card ;ASM which is the same as this ALC: MOV *SP,R1 SP=R9..has address of current SAMS reg# SLA R1,1 *2 (SAMS regs on even address boundaries) AI R1,>4000 compute SAMS register address LI R12,>1E00 load CRU of SAMS card SBO 0 turn on SAMS card MOV *R1,*SP read SAMS register SBZ 0 turn off SAMS card ...lee Quote Link to comment Share on other sites More sharing options...
Asmusr Posted March 22 Share Posted March 22 (edited) 29 minutes ago, Lee Stewart said: As I last posted, I did read back a SAMS register via MOV and received the page# in the MSB and the bank# in the LSB. The Classic99 debugger did not complain to me. So when run code on Classic99 it does let you read the SAMS registers. I only checked the memory view in the debugger and it was all zeros. Which is also how it is in JS99er now, and the reason I raised this issue, because I think it should show you the values of the SAMS registers. I will stop spamming this thread. Edited March 22 by Asmusr 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 22 Share Posted March 22 1 hour ago, Vorticon said: With the card initialization and detection sorted out, next I wrote a routine to find out the size of the card (number of pages). Well guess what? It's not working either 😭. It appears that the assigned register (here >4004 pointing to >2000 in low memory) will dutifully write to that memory location regardless of the value of the page/bank value assigned to it. That can't be right, but I checked with the debugger and it seems that way. The way I'm finding out the number of available pages is by assigning an incremental page/bank value to register >4004, writing a value in r2 (>FFFF) to >2000, then comparing >2000 to R2 again. If it matches, then the page is OK and we continue, otherwise we have reached the end of the available pages. That's how Harrison did it. Here is how I do it in fbForth (note that only pages are considered in the comments, i.e., the number representing bank:page is the number referred to below as “page” for simplicity): Spoiler ;[*++ Check for presence of SAMS card. ***++ SAMS flag will be set to highest available page#. * Testing will start with 32 MiB SAMS and will proceed by halving the range * until 128 KiB is reached. 128 KiB is assumed to be the lowest viable SAMS. * The actual page tested will be >000E higher than the lowest page in the * upper half of the range. * * To test, Map >000E + lowest page in upper half of SAMS range to >E000. For * 32 MiB, this is >1000 + >000E. We initially store >0010 (LSB,MSB) in * R3 to allow a circular shift each round before MOVing to R0 to then add * >0E00 (LSB,MSB) for the next test. If the test fails at >001E, the last * viable SAMS (128 KiB), R3 will go to >0800, at which point the loop * exits, setting R3 to 0, effectively reporting "no SAMS". * * Set up SAMS check. * LI R2,>994A check-value MOV R2,@>E000 check-value to check-location * Classic99 emulator can do 32 MiB LI R3,>0010 lowest page in upper half of SAMS to R3 (LSB,MSB) LI CRU,>1E00 CRU address of SAMS * * SAMS_CHECK: MOV R3,R0 lowest page in upper half of SAMS range AI R0,>0E00 get >000E pages higher SBO 0 enable SAMS registers MOV R0,@>401C poke SAMS register for >E000 SBZ 0 disable SAMS registers C @>E000,R2 compare possible copy with test value JNE SAMS_EXIT exit if SAMS mapped, viz., no match SRC R3,1 shift right circularly by ^2 to next lower SAMS CI R3,>0800 too far? JNE SAMS_CHECK try half as much if not >0008 (LSB,MSB) CLR R3 no-SAMS..set flag to 0 JMP SAMS_EXIT0 we're outta here SAMS_EXIT: SWPB R3 restore page# SLA R3,1 double value (highest page# + 1) DEC R3 decrement to highest page# SAMS_EXIT0: MOV R3,@ARG save SAMS flag to ARG (hoping it survives!) JEQ FRTHCP go to copying Forth inner interpreter if no SAMS * ...no need to restore anything if no SAMS * * Remap default page >0E to >E000. * CRU should still have correct value. * LI R0,>0E00 load SAMS page >000E SBO 0 enable SAMS registers MOV R0,@>401C poke SAMS register for >E000 SBZ 0 disable SAMS registers ;]* ...lee Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 22 Share Posted March 22 23 minutes ago, Lee Stewart said: Here is how I do it in fbForth (note that only pages are considered in the comments, i.e., the number representing bank:page is the number referred to below as “page” for simplicity): Hide contents ;[*++ Check for presence of SAMS card. ***++ SAMS flag will be set to highest available page#. * Testing will start with 32 MiB SAMS and will proceed by halving the range * until 128 KiB is reached. 128 KiB is assumed to be the lowest viable SAMS. * The actual page tested will be >000E higher than the lowest page in the * upper half of the range. * * To test, Map >000E + lowest page in upper half of SAMS range to >E000. For * 32 MiB, this is >1000 + >000E. We initially store >0010 (LSB,MSB) in * R3 to allow a circular shift each round before MOVing to R0 to then add * >0E00 (LSB,MSB) for the next test. If the test fails at >001E, the last * viable SAMS (128 KiB), R3 will go to >0800, at which point the loop * exits, setting R3 to 0, effectively reporting "no SAMS". * * Set up SAMS check. * LI R2,>994A check-value MOV R2,@>E000 check-value to check-location * Classic99 emulator can do 32 MiB LI R3,>0010 lowest page in upper half of SAMS to R3 (LSB,MSB) LI CRU,>1E00 CRU address of SAMS * * SAMS_CHECK: MOV R3,R0 lowest page in upper half of SAMS range AI R0,>0E00 get >000E pages higher SBO 0 enable SAMS registers MOV R0,@>401C poke SAMS register for >E000 SBZ 0 disable SAMS registers C @>E000,R2 compare possible copy with test value JNE SAMS_EXIT exit if SAMS mapped, viz., no match SRC R3,1 shift right circularly by ^2 to next lower SAMS CI R3,>0800 too far? JNE SAMS_CHECK try half as much if not >0008 (LSB,MSB) CLR R3 no-SAMS..set flag to 0 JMP SAMS_EXIT0 we're outta here SAMS_EXIT: SWPB R3 restore page# SLA R3,1 double value (highest page# + 1) DEC R3 decrement to highest page# SAMS_EXIT0: MOV R3,@ARG save SAMS flag to ARG (hoping it survives!) JEQ FRTHCP go to copying Forth inner interpreter if no SAMS * ...no need to restore anything if no SAMS * * Remap default page >0E to >E000. * CRU should still have correct value. * LI R0,>0E00 load SAMS page >000E SBO 0 enable SAMS registers MOV R0,@>401C poke SAMS register for >E000 SBZ 0 disable SAMS registers ;]* ...lee I don't understand the part where you check the contents of the write. You initially write a test value to >E000, turn on the card, load >401C with the page you want to test, turn off the card, then do a compare between the original test value in R2 and the contents of >E000. You don't have mapping on, so writing to >E000 really is just writing to the original location and not the test page. And why are you turning the card off before the compare operation? What am I missing? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 22 Share Posted March 22 I simplified my code a little, but still the same issue where any bank/page will work regardless of the size of the SAMS as verified by the debugger. I will have to try that on real hardware again tonight. .func samssize ;returns the number of pages available ;usage: sizeint := samssize .ref pcodeon,pcodoff,procret mov r11,@procret bl @pcodoff li r12,1e00h ;cru address of sams card sbo 0 ;turn on card clr r4 ;page counter li r1,15 ;page/bank register value li r2,0ffffh ;test value incpage ai r1,1 ;add page/bank starting at page >10 bank 0 swpb r1 mov r1,@4004h ;map address >2000 to page/bank sbo 1 ;turn on the mapper mov r2,@2000h ;write test value to >2000 c r2,@2000h ;did it write correctly? jne endpage swpb r1 clr @2000h inc r4 ;increment page counter sbz 1 ;turn off the mapper jmp incpage ;try next page endpage li r1,0200h ;restore original mapping mov r1,@4004h sbz 0 ;turn off sams card dec r4 mov r4,*r10 ;return page counter bl @pcodeon mov @procret,r11 b *r11 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 22 Share Posted March 22 (edited) 2 hours ago, Vorticon said: I don't understand the part where you check the contents of the write. You initially write a test value to >E000, turn on the card, load >401C with the page you want to test, turn off the card, then do a compare between the original test value in R2 and the contents of >E000. You don't have mapping on, so writing to >E000 really is just writing to the original location and not the test page. And why are you turning the card off before the compare operation? What am I missing? Sorry. Actually mapping is on before that code is run. I forgot to indicate that the first thing fbForth does is to initialize SAMS, whether or not it is present. You actually should not need to do this if you want the default mapping of page 2 to >2000, 3 to >3000, ..., >0F to >F000. At that point, I enable mapping (SBO 1) and never disable it. The code I posted is after this, so mapping is enabled. You are correct. I never write to the test page. If SAMS is operational at the page I test, it should not have the >994A value. If it does, there is either no SAMS or the attempted page swap failed because >994A should only ever exist in the original/initialized RAM location. Also, you only turn the card on for the brief moment you want to write to the SAMS registers. The card does not need to be on when you are writing to the actual mapped-in memory! Mapping, however, obviously needs to be enabled. ...lee Edited March 22 by Lee Stewart additional info Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 22 Share Posted March 22 50 minutes ago, Lee Stewart said: You are correct. I never write to the test page. If SAMS is operational at the page I test, it should not have the >994A value. If it does, there is either no SAMS or the attempted page swap failed because >994A should only ever exist in the original/initialized RAM location. But you are exiting the routine if the page is not equal to >994A. I'm confused Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 22 Share Posted March 22 So based on what @Lee Stewart said above, it seems I was testing the memory contents wrong. I was writing to the test page and reading it back, and apparently that will always be equal regardless of whether the actual page exists or not. Using what Lee did where I write a value to the initialized memory location, change the page then test of equality did the trick. Not necessarily evident by any means particularly when Harrison was doing what I was originally doing myself. Here's the now working source. It's so fast that I'm not bothering with skipping testing at the 128K boundaries which would complicate things and rather just going through all the pages sequentially. .func samssize ;returns the number of pages available ;usage: sizeint := samssize .ref pcodeon,pcodoff,procret mov r11,@procret bl @pcodoff li r12,1e00h ;cru address of sams card sbo 0 ;turn on card sbo 1 ;turn mapping on li r4,16 ;page counter. skip over first 16 pages li r1,15 ;page/bank register value mov @2000h,r3 ;save contents of test memory location li r2,0ffffh ;test value mov r2,@2000h ;low memory location used for testing incpage ai r1,1 ;add page/bank starting at page >10 bank 0 swpb r1 mov r1,@4004h ;map address >2000 to page/bank c r2,@2000h ;did it write correctly? jeq endpage ;new page should not equal initial value swpb r1 clr @2000h inc r4 ;increment page counter jmp incpage ;try next page endpage li r1,0200h ;restore original mapping mov r1,@4004h mov r3,@2000h ;restore contents of test memory location sbz 1 ;turn mapping off sbz 0 ;turn off sams card mov r4,*r10 ;return page counter bl @pcodeon mov @procret,r11 b *r11 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 22 Share Posted March 22 25 minutes ago, Vorticon said: But you are exiting the routine if the page is not equal to >994A. I'm confused I am coming from the highest possible SAMS size (32 MiB) down. The first time that I find the test location does not contain >994A, I know I have reached the highest mappable SAMS. You see, >994A should only ever exist in the initial location. If there is no SAMS, the test location will always show >994A. Once a successful mapping takes place, there is a different memory page swapped in that does not have >994A at the test location, hence the exit at that point. ...lee 4 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 23 Share Posted March 23 Tested on real hardware. Works. 20240323_051644.mp4 3 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 23 Share Posted March 23 Is there a way to pass arrays of different sizes to a single generic array parameter in a procedure call? Right now I have to create a Type declaration for an array of a specific size, declare an array of that type, and use it as a parameter in a procedure. The problem is that if I have a need for arrays of different sizes that can use the same procedure, I'll have to make Type declarations for each one as well as additional procedures to accept these new types. Obviously not a solution... Quote Link to comment Share on other sites More sharing options...
apersson850 Posted March 24 Author Share Posted March 24 (edited) Depends on the procedure. If you are calling an external procedure then there's no requirement that a parameter must have a type declaration. If it's a Pascal procedure you need to send a pointer to the array and a size specification to your subroutine. When specifying the size you may have use for the sizeof function, which returns the size of the parameter. The unit is bytes. So sizeof(an integer) will return 2. Don't forget about the intrinsics moveleft, moveright and fillchar when handling variable size arrays. When creating variable size arrays you may also find varnew, varavail and vardispose useful. Depending on how you declare your pointer, you may also need to turn range checking off in the surbroutine. Use the directive (*$R-*). When having a variable length array it's rather common to declare it as an vararray = array[0..0] of integer. Then the compiler will know how to index words into the array, but you'll get a out of range error as soon as you try to index outside zero. You can use vararray = packed array[0..0] of char if you want to index by byte. Edited March 26 by apersson850 2 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 24 Share Posted March 24 2 hours ago, apersson850 said: When having a variable length array it's rather common to declare it as an vararray = array[0..0] of integer. That's a new one to me. In this case I assume we have to use VARAVAIL and VARNEW to allocate the desired size? Quote Link to comment Share on other sites More sharing options...
apersson850 Posted March 24 Author Share Posted March 24 (edited) The difference between new and varnew is that with new, you allocate memory to hold a pre-declared type. With varnew you specify the size of the variable at that moment. In both cases you get a pointer to the beginning of the variable. If the area you are requesting is reasonable in size, you can just use varnew. If you, on the other hand, are interested in getting a buffer as large as conditions will permit, then you should check with varavail what you can get. Don't forget to list segments involved in system calls, if there are any. And your own program. Subtract a couple of hundred words for safety too. Note that sizeof lists the size in bytes but varnew and varavail work with words. Cauttion! You must use vardispose with the same size to return an allocated area! If you don't do that, or try to just dispose it, disaster will strike. If arrpoint is a pointer to ^vararray and buffer an integer, then you can do buffer := warnew(arrpoint, 100) to get an array with 100 words or 200 bytes. If the array is word-indexed you can use indexes in the range 0..99 inside the array. If you go to 100 or above you are accessing memory outside the array. Since the declared size is just one element range checking must be off. If buffer wasn't 100 after the call it failed. Edited March 24 by apersson850 1 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 25 Share Posted March 25 Taking a closer look at the 4k memory block from >2000 to >3000 in low memory expansion, it seems that it does not have anything critical to the execution to an assembly program in high memory, so SAMS pages can be loaded through that window safely as long as that block is restored prior to exiting to the host program. I tested it and no problem at all. Now I can use the full SAMS capacity. Cool. 4 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 25 Share Posted March 25 Here's a set of utilities for full access to the SAMS card on the p-system. I have plans for this Spoiler ;routines for sams card access ;walid maalouli ;march 2024 .func samsinit ;initialize the sams card and verify card is present ;returns 0 for absent and 1 for present ;usage: statusint := samsinit .def procret,pmeret,pcodeon,pcodoff mov r11,@procret bl @pcodoff li r12,1e00h ;cru address of sams card sbo 0 ;turn card on li r1,0ff00h li r0,4000h ;start address of sams registers nxtpage ai r1,0100h ;increment page number starting at 0 mov r1,*r0+ ;load page number into sams register ci r0,4020h ;beyond last register (401eh)? jlt nxtpage c r1,@401eh ;if match then card present jne nocard li r2,1 jmp endinit nocard clr r2 endinit mov r2,*r10 ;place card indicator on return stack sbz 0 ;turn sams card off bl @pcodeon mov @procret,r11 b *r11 pcodeon li r12,1f00h ;activate the pcode card sbo 0 mov @pmeret,r12 ;restore the pme pointer b *r11 pcodoff mov r12,@pmeret ;save the pme pointer li r12,1f00h ;deactivate the pcode card sbz 0 b *r11 pmeret .word procret .word .func samssize ;returns the number of pages available ;usage: sizeint := samssize .ref pcodeon,pcodoff,procret mov r11,@procret bl @pcodoff li r12,1e00h ;cru address of sams card sbo 0 ;turn on card sbo 1 ;turn mapping on li r4,16 ;page counter. skip over first 16 pages li r1,15 ;starting bank/page mov @2000h,r3 ;save contents of test memory location li r2,0ffffh ;test value mov r2,@2000h ;load test memory with value incpage ai r1,1 ;add page/bank starting at page >10 bank 0 swpb r1 mov r1,@4004h ;map address >2000 to page/bank c r2,@2000h ;did it write correctly? jeq endpage ;new page should not equal initial value swpb r1 inc r4 ;increment page counter jmp incpage ;try next page endpage li r1,0200h ;restore original mapping mov r1,@4004h mov r3,@2000h ;restore contents of test memory location sbz 1 ;turn mapping off sbz 0 ;turn off sams card mov r4,*r10 ;return page counter bl @pcodeon mov @procret,r11 b *r11 .proc dataops,5 ;read/save data to sams pages up maximum capacity ;usage: dataops(rwcode, startpage, datasize, offset, data) ;rwcode : 1=save, 2=read ;startpage is the starting page for the save operation. ;subsequent pages will be automatically assigned if needed ;datasize can be obtained by sizeof(data) ;offset is the number of bytes from the start of the page ;data is a packed array of byte .ref pcodeon,pcodoff,procret mov r11,@procret bl @pcodoff mov *r10+,r4 ;get pointer to starting page number mov *R10+,r3 ;get pointer to number of bytes to transfer mov *r10+,r2 ;get pointer to page offset mov *r10+,r1 ;get pointer to data li r6,4004h ;starting sams register (memory >2000) li r12,1e00h ;cru address of sams card sbo 0 ;turn card on li r5,2000h ;base memory address a *r3,r5 ;apply byte offset mov *r3,r0 ;store offset in byte counter at start mov *r10,r3 ;get r/w code sbo 1 ;turn mapper on nxtpage swpb *r1 mov *r1,*r6 ;assign page to sams register swpb *r1 rwops ci r3,1 ;is it a write operation? jne getops saveops mov *r4+,*r5+ ;save 2 bytes at a time (word) jmp contops getops mov *r5+,*r4+ ;get 2 bytes at a time contops dect *r2 jle opsdone ;no more data inct r0 ci r0,4096 ;are we past 4k of data? jlt rwops inc *r1 ;next page number clr r0 jmp nxtpage ;continue data ops opsdone li r1,0200h ;restore sams register to original page mov r1,@4004h sbz 1 ;turn mapper off sbz 0 ;turn off sams card bl @pcodeon mov @procret,r11 b *r11 .end 5 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 25 Share Posted March 25 So this is a nice bi-directional block move to/from Pascal & SAMS. How does it work from the PASCAL side? Will you be reading chunks of SAMS data into PASCAL structures? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 25 Share Posted March 25 1 hour ago, TheBF said: So this is a nice bi-directional block move to/from Pascal & SAMS. How does it work from the PASCAL side? Will you be reading chunks of SAMS data into PASCAL structures? The utility uses a packed array of bytes for data transfers back and forth and a transfer could be done in one pass provided there is a large enough array available. Otherwise it will have to be broken up into smaller chunks up to the maximum ram size of the SAMS. The Pascal program can then take care of converting the array to some other structure if needed. There is complete control over where in SAMS the data is stored or retrieved down to the byte level and consecutive pages are brought in as needed automatically, so different data sets can easily coexist. 2 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted March 26 Share Posted March 26 On 3/22/2024 at 11:34 AM, Asmusr said: Maybe some of the confusion about whether you should write the same value to both the MSB and the LSB of a SAMs register is because when you read the value back - even if you have only written to the MSB - both MSB and LSB contain the same value. That's at least how it is in MAME according to the debugger. Classic 99 doesn't seem to let you read the register values back at all, again according to the debugger. That's a debugger problem. Hardware registers only show up in there if I specifically coded them. You have to use the "command line interface" to see the AMS registers (help 'HELP' in the address box and watch the debug log). One of the many places that Classic99 is applying pressure to its seams. 2 Quote Link to comment Share on other sites More sharing options...
apersson850 Posted March 26 Author Share Posted March 26 On 3/25/2024 at 10:52 PM, Vorticon said: The utility uses a packed array of bytes for data transfers back and forth and a transfer could be done in one pass provided there is a large enough array available. Otherwise it will have to be broken up into smaller chunks up to the maximum ram size of the SAMS. The Pascal program can then take care of converting the array to some other structure if needed. There is complete control over where in SAMS the data is stored or retrieved down to the byte level and consecutive pages are brought in as needed automatically, so different data sets can easily coexist. Which is completely equivalent to reading/writing a file. You create a file buffer and put/get the data. I'm still of the opinion that you would be better off creating a driver which makes SAMS look like disk drives to the p-system instead. Then you accomplish the same thing with file instructions. You get the advantage that the program will run on machines without SAMS too, just much slower, using a real disk. Plus you can store the system programs Editor, Filer, Compiler, Assembler and Linker on the RAM drive and have them run faster. The only limitation I immediately see is the maximum useful size of such a RAM drive, since it would be preferable if it's not bigger than the file system and filer can handle it. There's a limit of 32767 records in a file, for example. There is some limit to the max number of blocks on a volume too, but I don't remember it right now. Have to check some documentation. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 26 Share Posted March 26 20 minutes ago, apersson850 said: Which is completely equivalent to reading/writing a file. You create a file buffer and put/get the data. Yes, but much quicker access by far. The way I see this used is to load data from disk and store it in SAMS at the start of a program, then subsequently access that data directly. Think of some kind of large game map for example updatable in real time. It will stay in SAMS instead of taking up standard system memory yet remain easily accessible. Or perhaps a large data set the requires some kind of transformation before storing back to disk. Again it can be easily accessed without affecting available memory for the main program. Quote Link to comment Share on other sites More sharing options...
apersson850 Posted March 27 Author Share Posted March 27 (edited) Well, if you need that speed, then sure. That's the best way. I have problems seeing a more complex game, written in Pascal, which can take advantage of such a screen update concept at such speeds that your design is necessary. For such purposes I would imagine the RAMdisk concept would be quick enough, or a larger part of the game has to run in assembly. But I have no real experience from exactly this. It's just a hunch. Regarding the feasibility of making a large RAMdisk - I checked the directory structure and all block numbers are integers. Thus you can have 32768 blocks, or 16 megabytes of memory on a single disk. Only 77 files, but if you map a memory expansion into one file, you don't need any more. Edited March 27 by apersson850 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted March 28 Share Posted March 28 3 hours ago, apersson850 said: have problems seeing a more complex game, written in Pascal, which can take advantage of such a screen update concept at such speeds that your design is necessary. For such purposes I would imagine the RAMdisk concept would be quick enough, or a larger part of the game has to run in assembly. The update speed to the game map in such a game is important to keep play from dragging on. Remember that hypothetical map is too large to reside in main memory, so it's either a disk drive or SAMS. Imagine how slow it would be to constantly access the disk drive everytime a change is made... Now a RAM disk would be ideal I agree, but turning the SAMS into one is not a straightforward process given it's access limitations in the p-system. I'm happy enough with the SAMS as it stands currently 🙂 2 Quote Link to comment Share on other sites More sharing options...
apersson850 Posted March 28 Author Share Posted March 28 If I understand you correctly, SAMS is accessed via a window, into which you map whichever physical memory page you like in the SAMS device. That window may be a memory expansion part, like 2000-3FFFH or it could be the DSR page, 4000-5FFFH. Now I may have misunderstood the details (I've not worked with SAMS at all), but hopefully I have the core idea correct here. If so, then it's not any different than my home-made RAM-disk, which consists of the 64 K RAM i have "sleeping" in my internal memory expansion plus the 56 K (16 K RAM and 40 K GRAM) in my Maximem module. Now I conveniently have a card with RAM at 4000-47FFH, enabled by a CRU bit just like any DSR, where I can put the DSR for using this 120 K RAM as a RAM-disk with the p-system. My RAM-disk even uses the RAM at 4000-5FFFH, but then it has to disable itself, so first it must move code into other RAM and thus save what's there before returning. This complicates it a bit, but I took that effort just to be able to use the whole RAM available. With the much larger space available in SAMS, there's no point in such trickery. That process would be significantly more straight forward. You will also gain the advantage of compiling at twice the speed on the real machine, with the compiler on the RAM-disk. Even faster if source and code are on the RAM-disk too. For the purpose of the game, I agree, you are (and should be) happy with what you have. Being an industrial developer for 40 years, I look around the corner already before being there, out of habit... 3 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.