Joined: Fri May 05, 2017 9:27 pm Posts: 895
|
I do not recall an SD card for the C64. I do know that there were Ram Expansion Modules available for the C64 and C128. The module plugged into the expansion port (cartridge port). As for the disk drives, they were external units interfaced by a serial cable, a serial version of IEEE-488. The drives had two connectors for the serial cable so multiple units could be 'daisy chained' together. Device numbers 8 and up were typically for disk drives.
I think I've mentioned this elsewhere, Fleet Forth determines which drive to use for block access based on block number. Originally, only five drives were supported but it takes less code to support eight drives. Here a table showing which block numbers go to which drive.
Code: Actual | C64 | device block range | device | block range | | 0 - $0FFF | 8 | 0 - $0FFF $1000 - $1FFF | 9 | 0 - $0FFF $2000 - $2FFF | 10 | 0 - $0FFF $3000 - $3FFF | 11 | 0 - $0FFF $4000 - $4FFF | 12 | 0 - $0FFF $5000 - $5FFF | 13 | 0 - $0FFF $6000 - $6FFF | 14 | 0 - $0FFF $7000 - $7FFF | 15 | 0 - $0FFF $8000 - $FFFF | REU | 0 - $7FFF
Block numbers are unsigned. The code word R/W determines which device is used.
Code: HEX CODE R/W ( ADR BLK# R/WF CNT -- ) BEGIN, SEC, 5 ,X LDA, 10 # SBC, CS WHILE, 5 ,X STA, INY, 8 # CPY, 0= UNTIL, ' RR/W SPLIT SWAP # LDA, # LDY, (EXECUTE) 0= NOT BRAN, THEN, DRB STY, ' DR/W SPLIT SWAP # LDA, # LDY, (EXECUTE) 0= NOT BRAN, END-CODE
(EXECUTE) is a metacompiler label that points into EXECUTE . The two branches into the body of EXECUTE are always taken. A branch always instruction would have been nice but the C64 has the 6510 processor. No CMOS version.
Code: HEX CODE EXECUTE ( ADR -- ) 0 ,X LDA, 1 ,X LDY, INX, INX, LABEL (EXECUTE) W 1+ STY, W STA, 0 # LDY, W 1- JMP, END-CODE
Although the system will choose a specific drive for each range of 4096 blocks, not all blocks will be available. For example, if device 8 is a Commodore 1541 drive, only 166 blocks are available. This means that the range of available blocks is not continuous. The range selected for the drives is a design consideration I made to facilitate copying blocks from one device to another while allowing a larger capacity drive to have more blocks available than what is possible with the 1541 drive. The maximum REU size that is compatible with other C64 REU's is 16 megabytes or 16384 blocks. The 1764 REU had a capacity of 256 blocks and the 1750 REU had a capacity of 512 blocks.
For block numbers less than $8000, the deferred word DR/W is called otherwise the deferred word RR/W is called.
Fleet Forth has the helper words DR+ and RAM to help hide this, or at least make it so the exact numbers do not need to be known. RAM just adds $8000 to the number on the stack. One use for blocks in the REU is virtual memory.
DR+ takes two parameters, the block number and the drive to use. If I want to see an INDEX of the first 10 blocks on drive 9 I would type this:
Code: 0 9 DR+ 10 9 DR+ INDEX
Note: For drive 8, DR+ is not needed. This:
Code: 5 8 DR+ BLOCK
Is effectively the same as this:
Code: 5 BLOCK
I placed Fleet Forth's system loader in drive 9 and got an index while the base was 16 and then set it to decimal and got the index again. This is the log of the session. Both what I typed and the computer's responses are shown.
Code: OK 0 9 DR+ 10 9 DR+ INDEX 1000 *********************************** 1001 // LOAD BLOCK 1002 // 2ND LOAD BLOCK -- EMPTY 1003 // DONE? THRU 1004 // SYSTEM CONSTANTS 1005 // OPCODE OFFSET TABLE AND MODES 1006 // BOT SEC RP) 1007 // CPU0 & IMPLIED ADDRESSING 1008 // CPU1 1009 // W/OUT IMPLIED ADDRESSING MODE 100A // W/OUT IMPLIED ADDRESSING MODE 100B // ?EXEC NOT OFFSET BRANCHES 100C // THEN, 100D // AHEAD, IF, ELSE, WHILE, ELIF, 100E // BEGIN, AGAIN, UNTIL, REPEAT, BRAN, 100F // SUBR CODE ;CODE END-CODE 1010 // >FORTH >ASSEM OK DECIMAL OK 0 9 DR+ 16 9 DR+ INDEX 4096 *********************************** 4097 // LOAD BLOCK 4098 // 2ND LOAD BLOCK -- EMPTY 4099 // DONE? THRU 4100 // SYSTEM CONSTANTS 4101 // OPCODE OFFSET TABLE AND MODES 4102 // BOT SEC RP) 4103 // CPU0 & IMPLIED ADDRESSING 4104 // CPU1 4105 // W/OUT IMPLIED ADDRESSING MODE 4106 // W/OUT IMPLIED ADDRESSING MODE 4107 // ?EXEC NOT OFFSET BRANCHES 4108 // THEN, 4109 // AHEAD, IF, ELSE, WHILE, ELIF, 4110 // BEGIN, AGAIN, UNTIL, REPEAT, BRAN, 4111 // SUBR CODE ;CODE END-CODE 4112 // >FORTH >ASSEM OK CONSOLE
Fleet Forth does not store blocks in sequential files. Commodore sequential files are not random access. Fleet Forth, like Blazin' Forth, uses direct access to read four 256 byte disk sectors per Forth block. The sector mapping for the 1541 drive is compatible with Blazin' Forth. In other words, Fleet Forth can read blocks from a 1541 disk used by Blazin' Forth and vice versa. I know that C64 Forth by Tom Zimmer used Commodore relative files for blocks and I may experiment with that approach one day.
To be able to access blocks on a disk, the drive must be opened with the word DOPEN . This word takes no parameters and leaves no parameters. It opens the disk on the current drive. The current drive is 8 upon startup or a cold start but can be changed with the word DRIVE . For example, if I wanted to access blocks on drives 8 and 9, I could do the following:
Code: 8 DRIVE DOPEN 9 DRIVE DOPEN
If I know that the current drive is drive 8, I could leave off the phrase '8 DRIVE'. Before removing a disk from a drive, the drive must be closed with the word DCLOSE . DCLOSE also takes no parameters and leaves no parameters. As with opening a drive for block access, if I want to close a drive for block access, it needs to be the current drive. After the previous example drive 9 is the current drive.
Code: 8 DRIVE DCLOSE
Now 8 is the current drive again.
Fleet Forth maintains one or more buffers for blocks. I usually use four, but I sometimes use more when manipulating blocks. The buffers are right up against the memory limit specified by the system value LIMIT . LIMIT can be lowered if the need arises. The buffer access table sits right up against the buffers. Although Fleet Forth reads blocks using direct access to read four Commodore disk sectors, it reads each block as a one kilobyte chunk. Fleet Forth only reads one block at a time and only writes one block at a time. The following will change the number of block buffers.
Code: n TO #BUF CONFIGURE
Since DR/W is a deferred word, it can be re-vectored to a new word to allow access to different hardware. It could even be re-vectored to a word that used Commodore relative files for blocks.
Since RR/W is also a deferred word, it can also be re-vectored. Instead of using a Commodore Ram Expansion Unit, it could be re-vectored to a word that uses a hard drive for the blocks in the range $8000 to $FFFF. I hope this helps.
|
|