Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boot from SD card #107

Open
kervinck opened this issue Sep 14, 2019 · 3 comments
Open

Boot from SD card #107

kervinck opened this issue Sep 14, 2019 · 3 comments
Assignees
Labels
Milestone

Comments

@kervinck
Copy link
Owner

kervinck commented Sep 14, 2019

Minimum plan to untether the Gigatron from Arduino/Babelfish and special laptop/PC software (sendFile.py).

Building on top of CardTest:

  1. Detect presence of SDC/MMC card connected to the I/O expander board. Recognise the major types.
  2. Scan the FAT32 root directory
  3. Look for something like a BOOT.GT1 file
  4. Read the file into memory and run it. If it is small enough to fit in a cluster (typically 8K), we might not even need the FAT tables
  5. Put this either in the Reset.gcl, in the Eater Egg, or in Loader
  6. Release a next ROM version ("ROM v5")
  7. Update the expander board design and release the gerbers. With this, people can order bare boards for ~5$ at their favourite PCB maker. TTL chips and card interface can come from major vendors. No need to go "full kit" in the beta-phase. This is all cheap stuff.

From here we can bootstrap a lot of new functionality: full filesystem support (R/W), applications, operating system, editors...

@kervinck kervinck added this to the ROM v5 milestone Sep 14, 2019
kervinck added a commit that referenced this issue Sep 15, 2019
This is a step towards booting from a memory card
For now requires that the file fits in 512 bytes
For example Hello.gt1
@kervinck kervinck changed the title Boot from SDC/MCC card Boot from SDC/MMC card Sep 19, 2019
@kervinck
Copy link
Owner Author

kervinck commented Sep 24, 2019

We've gotten CardTest.gcl as far that it can load and run BOOT.GT1 files, even if they span multiple clusters. The entire loader is 2.5K of vCPU code, and that includes functions that are not strictly needed (directory listing for example). We can strip down the core to about 1.5K. This 1.5K excludes the card setup code, because that's allowed to be overwritten.

On a 64K system we can easily stow this in the upper pages. E.g. $fa00..$ffff. On 128K systems we can even hide it in a memory bank. On 32K systems it's more difficult to find a place that doesn't conflict with GT1 files that are already out there. So it would go into normally-visible screen memory. Still, some GT1 files load directly there as well: Contrib/tbraun-de/tools/shuttle.gt1 is an extreme example. Mind that the the older serial Loader region (page $59, $5a, $5b) is too small for an SDC/MMC loader (most of the work is done by the Arduino and some application-specific SYS functions there).

But we must make an honest attempt that Tetronis, Bricks and Gigatris load ok from SDC/MMC. The best seems to be to use more screen memory than Loader, and only the first 160 bytes of each page, not protruding into the high 96 bytes.

But doing that doesn't solve all issues: a very significant portion of the zero page is in use as well, stretching from $30 to above $c0. Even when we require 64K of RAM, this presents a conflict for many GT1 files out there and must be solved.

Approach 1
The lame approach is to initially load any zero page data into page 1 (videoTable), and at the end copy to page 0 and restore page 1. This will mangle the screen display momentarily, but we can restore it completely after copying. Good to know: no GT1 files currently load anything in page 1.

Approach 2
Or we follow a two-stage approach:

Step 1. Load the entire GT1 file into memory, in one large continuous chunk.
Step 2. Then unfold the GT1 structure and copy the segments to their designated location

The thought is that step 2 hardly needs any code space and variables. It is essentially the same size as the ROM loader that SYS_Exec_88 places on the stack: less than 64 bytes.

At first sight it appears that between the two steps, we need a large block move from low memory to high memory. But we can avoid that if we use the file size attribute to calculate the start address.

The advantage of this approach is that we can do faster block transfers on the SPI interface, and complete CRC checking before unfolding.

The disadvantage is that this mangles the display without restoration. So it isn't suitable for an interactive command prompt environment, if we want that as well.

Approach 3
We can also try squeeze the core zero page usage into $c0-$ff. This requires more than halving the variable pressure. The only way I see how this can be achieved is with the proposed CALLI instruction: https://forum.gigatron.io/viewtopic.php?p=935#p935
With this we eliminate the need for function pointers in zero page. Obviously this won't work with ROMv4, but a ROM upgrade is required anyway for the boot loader itself.

To be continued....

@kervinck
Copy link
Owner Author

kervinck commented Sep 24, 2019

Regarding approach 3:

We currently have 81 GCL variables in CardTest.gcl (162 bytes), of which 51 variables are function pointers for use by CALL.

Variables count 81 bytes 162 end $00d3
 : ACMD41 [50] AddOffset [41] Address Buffer [14] CMD0 [52] CMD16 [33]
 : CMD17 [60] CMD55 [33] CMD58 [54] CMD8 [72] CardReply CardType
 : Checksum ClusterBaseH ClusterBaseL ClusterSize ClusterToSector [47]
 : CurrentDirH CurrentDirL DisableCard [14] EnableCard [14] Execute [31]
 : FatBaseH FatBaseL FilePosH FilePosL FileSizeH FileSizeL InitCard [51]
 : InitFat32 [93] IsBootGt1 [44] List LoadByte [57] LoadGt1 [86]
 : Newline [71] NextCluster [87] NextSector [34] Number OffsetH OffsetL
 : OpenFile [44] OpenSector [23] Pos PrintByte [24] PrintChar [76]
 : PrintDate [52] PrintDigit [40] PrintDirEntry [26] PrintDirectory [84]
 : PrintHexDigit [21] PrintName [52] PrintResult [35] PrintSize [90]
 : PrintText [31] PrintTwoDecimals [22] PrintValue [16]
 : PrintVolumeLabel [42] PrintWord [16] ReadClusterChain [71]
 : ReadDirectory [20] ReadMBR [74] ReadSector [52] ReadVolumeID [36]
 : SafePrintChar [26] SectorH SectorL SectorToByte [32]
 : SendCommandToCard [57] SendOnesToCard [25] ShiftLeft [18]
 : UpdateCrc16 [39] ValueH ValueL ValueToDecimal [93]
 : WaitForCardReply [30] i j k m p q

So the introduction of CALLI can reduce the zero page pressure to 30 variables, or 60 bytes. We also need some stack space, so keeping the footprint constrained to $c0..$ff remains a challenge.

And it doesn't allow Tetronis and Bricks to be loaded without altering those (as suggested in #41). If we can avoid modifying these programs, that is better.

@kervinck kervinck changed the title Boot from SDC/MMC card Boot from SD card Jan 25, 2020
@lb3361
Copy link
Contributor

lb3361 commented Aug 25, 2022

Suggesting to close this issue since CardBoot works now (devrom)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants