Jump to content
IGNORED

Pascal on the 99/4A


apersson850

Recommended Posts

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by Asmusr
  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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

 

 

Link to comment
Share on other sites

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 by Lee Stewart
additional info
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

 

  • Like 1
Link to comment
Share on other sites

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

  • Like 4
Link to comment
Share on other sites

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...

 

 

Link to comment
Share on other sites

Posted (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 by apersson850
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

Posted (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 by apersson850
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

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.

  • Like 4
Link to comment
Share on other sites

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

 

 

  • Like 5
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

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. ;)

 

  • Like 2
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Posted (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 by apersson850
Link to comment
Share on other sites

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 🙂

  • Like 2
Link to comment
Share on other sites

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...

  • Like 3
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...