The Silicon Disk rom has a command "|SETCPMPLUS" which patches the Amstrad CP/M with support for the Silicon disk. The resulting EMS file is called CPM3SEMI.EMS.
===Technical===
The |SETCPMPLUS command creates a file called PATCHER.COM, which contains (at offset 689h) a table of changes to make. The changes are made blindly to the first EMS file that PATCHER.COM finds; the user is responsible for ensuring it is run on a genuine C10CPM3.EMS.
Each change is formed:
DW start ;Address of first byte to change
DW end ;Address of last byte to change
DB data ;Replacement bytes
The addresses are as if the EMS file was loaded at 0100h.
====Initialisation====
The first few changes are to the initialisation code at the start of the EMS file:
DW 107h ;Replace a call to 0BD19h (MC_WAIT_FLYBACK) with a
DW 108h ;call to initialise the ramdisc.
DW 7100h
DW 1C5h ;Remove the LDIR that clears memory between
DW 1C6h ;0FE58h and 0FF9Fh (this has been populated by the.
DW 0 ;initialisation call).
DW 1D5h ;Place a RET at the start of the firmware version
DW 1D5h ;check, so that CP/M will run on a 464/664.
DB 0C9h
DW 358h ;Display the Silicon Disk sign-on message.
DW 359h
DW 0FE80h
The first change sets up the call to the code that initialises the ramdisc. This code consists of 512 bytes added to the end of the EMS file; since it is not trying to fit in spare space within the existing CP/M system, it is not as constrained for memory as the other patches.
The initialisation code copies itself to 0100h, and runs from there. The first thing it does is probe for available memory. There are two possible memory ranges: 192k (banks CC-CF, D4-D7, DC-DF) and 256k (banks E4-E7, EC-EF, F4-F7, FC-FF). The ramdisc can occupy either or both. If neither range is available, no drive is added to the system, and a minimal version of the sign-on routine (which displays no message) is constructed at 0FE80h.
Assuming that memory was found, the DPH for the new drive is added to the drive table. The first memory bank of the ramdisc is paged in, and the system checks that the first byte of each directory entry is either 0E5h or 00h-0Fh. If it is not, the entire first bank is cleared to 0E5h. This means that the presence of CP/M disc labels or date stamps will cause the ramdisc to be erased on boot.
The appropriate DPB for the size of ramdisc is copied to 0FF53h and the sign-on message altered to hold the correct size. The full version of the sign-on code is copied to 0FE80h.
Finally memory from 0FF64h to 0FF9Fh is blanked and the code resumes the normal initialisation sequence by jumping to MC_WAIT_FLYBACK.
====Helper functions====
After initialisation, the next two patches are helper functions, which occupy free space between CP/M modules. One is at 03E9h, in the gap between the CD and TE modules; the other at 0EE2h, in the gap at the end of DD. The first one backs up 128 bytes of memory at 8080h (which is normally used by the font) so it becomes available as a transfer buffer. The second reverses this, restoring the font.
Disk access
The disk access functions follow; these are placed between 8960h and 89FFh, in memory that's probably reserved for the system message table. Since they page memory, they switch to a local stack, which grows down from 3CFEh.
The actual I/O functions are reasonably simple. READ pages in the correct bank, copies 128 bytes to the transfer buffer at 8080h, and then uses the CP/M XMOVE and MOVE functions to copy the data to the right place. WRITE performs similar operations in reverse order; XMOVE and MOVE to get the data to 8080h, then page in the correct bank and copy the data there.
The other two operations are LOGIN (which consists simply of
EX DE, HL ;DPH is passed in DE, should be returned in HL on
RET ;success
) and FLUSH (a simple RET).
====Banked BIOS====
The next few changes allocate space for the extra DPB. In a stock CPC CP/M Plus, the stack grows down from 0FF64h. In CPM3SEMI this is lowered to 0FF53h, freeing up 17 bytes for the drive DPB.
Space also needs to be allocated for the DPH. The existing subroutine at 3FE0h is moved to 3FD0h (removing 16 apparently unused bytes) and then the new DPH occupies 3FD7h - 3FF9h.
The new drive also requires space for an allocation vector. This is placed at 3C89h, in memory intended for patches to the BDOS.
== CPM2.2 with Memory Expansions ==