{"id":1315,"date":"2019-05-19T11:24:29","date_gmt":"2019-05-19T09:24:29","guid":{"rendered":"https:\/\/www.pagetable.com\/?p=1315"},"modified":"2019-05-19T11:24:29","modified_gmt":"2019-05-19T09:24:29","slug":"run-cp-m-on-your-c64-using-emulation","status":"publish","type":"post","link":"https:\/\/www.pagetable.com\/?p=1315","title":{"rendered":"Run CP\/M on your C64 &#8211; using Emulation!"},"content":{"rendered":"<p>In this episode of computer archeology, we deconstruct a very interesting case of borrowing code from multiple places &#8211; but first try this D64 disk image with any Commodore 64 emulator or a real C64:<\/p>\n<p><a href=\"docs\/cpm_emu\/cpm_emu.d64\"><img loading=\"lazy\" decoding=\"async\" src=\"docs\/d64.png\" height=\"64\" width=\"64\" alt=\"\" \/><br \/>\nCommodore 64 CP\/M Emulator<\/a><\/p>\n<p>The CP\/M operating system was the first home computer OS that ran on machines from many different vendors, as long as they had an Intel 8080 compatible CPU &#8211; which the 8 bit machines from Commodore, Apple, Atari and BBC didn&rsquo;t: They used the MOS 6502 CPU.<\/p>\n<h3 id=\"The-Commodore-64-CPM-Cartridge\">The Commodore 64 CPM Cartridge<\/h3>\n<p>In 1983, Commodore released the the &ldquo;<a href=\"https:\/\/www.pagetable.com\/?p=1312\">CP\/M Cartridge<\/a>&rdquo; for the Commodore 64, which contained a Z80 CPU and came with CP\/M 2.2: The OS and its apps would run on the Z80, which would switch over to the computer&rsquo;s 6502 to call code in the original ROM for screen, keyboard and disk accesses. It wasn&rsquo;t very good, didn&rsquo;t sell well, and was quickly discontinued.<\/p>\n<h3 id=\"Ro\u00dfm\u00f6ller's-CP\/M-Emulator\">Ro\u00dfm\u00f6ller&rsquo;s CP\/M Emulator<\/h3>\n<p>But it was also possible to run CP\/M on a C64 without a hardware extension: All that is necessary is to emulate the Intel 8080 instruction set on the MOS 6502. And the German company Ro\u00dfm\u00f6ller did exactly that. In 1988, a little while after releasing their 4 MHz speeder cartridge &ldquo;<a href=\"http:\/\/www.retroport.de\/Hardware_T-U.html\">Turbo Process<\/a>&rdquo; for the C64, they started selling<\/p>\n<blockquote>\n<blockquote>\n<p>CP\/M Emulator &#8211; CP\/M 2.2-kompatibler C64 ohne zus\u00e4tzl. Hardware<\/p>\n<\/blockquote>\n<\/blockquote>\n<p>for 10 DM.<\/p>\n<p>The product is directly based on Commodore&rsquo;s adaption of CP\/M for the C64 CP\/M cartridge. Commodore&rsquo;s disk contains a small bootloader that loads BIOS and the Z80 bootstrap from the first sectors on disk (as specified by CP\/M) &#8211; the bootloader of the CP\/M Emulator directly contains slightly patched versions of BIOS and the Z80 bootstrap, as well as the 8080 emulator:<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<th>CP\/M Cartridge<\/th>\n<th>CP\/M Emulator<\/th>\n<\/tr>\n<tr>\n<td>\n<pre>0 \"CP\/M DISK       \" 65 2A\n1     \"CPM             \"  PRG\n0 BLOCKS FREE.\n<\/pre>\n<\/td>\n<td>\n<pre>0 \"CP\/M EMULATOR   \" 32 0B\n12    \"CP\/M            \"  PRG\n0 BLOCKS FREE.\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The first sectors on disk still contain the original versions of BIOS and the Z80 bootstrap &#8211; and curiously, all references on disk to &ldquo;Digital Research&rdquo;, the CP\/M license holder, have been replaced with &ldquo;Ro\u00dfm\u00f6ller&rdquo;, hinting towards a very questionable licensing status &#8211; not inconsistent with Ro\u00dfm\u00f6ller&rsquo;s reputation at the time.<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<th>CP\/M Cartridge<\/th>\n<th>CP\/M Emulator<\/th>\n<\/tr>\n<tr>\n<td>\n<pre>\n    COMMODORE 64   44k CP\/M vers 2.2\n\n  Copyright (C) 1979, Digital Research\n     Copyright (C) 1982, Commodore\n\nA>\n<\/pre>\n<\/td>\n<td>\n<pre>     R 03 07\n\n    COMMODORE 64  44k CP\/M vers 2.2\n\n    ===============================\n\n    Copyright (C) 1988, ROSSMOELLER\n\nA>\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"Emulator-Performance\">Emulator Performance<\/h3>\n<p>The Ro\u00dfm\u00f6ller 8080 emulator contained in the boot program is less than 1.4 KB in size &#8211; and it&rsquo;s super slow: Executing a single 8080 instruction takes between 300 and 800 cycles (485 on average). This makes the CP\/M emulator about 100 times slower than a similarly spec&#8217;ed 8080-based machine. Even with the 8 MHz speeder, the emulator was still 12 times slower. It was in fact so slow that it failed to register normal keypresses on stock C64 systems unless you held the keys for a second.<\/p>\n<h3 id=\"8080-Simulator-for-the-6502\">8080 Simulator for the 6502<\/h3>\n<p>There is a simple reason the emulator is this slow: It wasn&rsquo;t written for speed. It wasn&rsquo;t even written as an emulator. As it turns out, the Ro\u00dfm\u00f6ller 8080 emulator is a binary-patched version of the <a href=\"https:\/\/www.pagetable.com\/?p=824\"><em>8080 Simulator for the 6502, KIM-1 Version<\/em><\/a> &ldquo;<em>8080 simulator-debug package<\/em>&rdquo; by Dann McCreary, written in 1978.<\/p>\n<p><em>8080 Simulator for the 6502<\/em> is an interactive 8080 simulator primarily aimed at teaching 8080 assembly &#8211; and optimized for size, since it had to to fit into the 2 KB of RAM of the KIM-1.<\/p>\n<p>In the following implementation of the memory access instructions STAX\/LDAX, you can see that the Ro\u00dfm\u00f6ller version just relocated everything by $CA pages:<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<th>8080 Simulator for the 6502<\/th>\n<th>Ro\u00dfm\u00f6ller CP\/M Emulator<\/th>\n<\/tr>\n<tr>\n<td>\n<pre>0249 DIRECT  PHA         ; TEMP SAVE\n024A         JSR PC\/PNT  ; PC TO POINTER\n024D         JSR DBLINC\n0250         LDXIM (SCR)\n0252         JSR MEM\/RP\n0255         LDXIM (PNT)\n0257         JSR SRC\/RP\n025A         PLA         ; RECOVER TEMP\n025B         LSRA        ; LOAD?\n025C         BCS STORE   ; NO, STORE\n025E         ASLA        ; MAKE INDEX\n025F         TAX\n0260         BEQ LDAD    ; LOAD A DIRECT?\n0262         JMP MEM\/RP  ; NO, LOAD HL DIRECT\n<\/pre>\n<\/td>\n<td>\n<pre>.,CC49 48       PHA\n.,CC4A 20 5D CD JSR $CD5D\n.,CC4D 20 80 CD JSR $CD80\n.,CC50 A2 19    LDX #$19\n.,CC52 20 A0 CD JSR $CDA0\n.,CC55 A2 17    LDX #$17\n.,CC57 20 70 CD JSR $CD70\n.,CC5A 68       PLA\n.,CC5B 4A       LSR A\n.,CC5C B0 0E    BCS $CC6C\n.,CC5E 0A       ASL A\n.,CC5F AA       TAX\n.,CC60 F0 03    BEQ $CC65\n.,CC62 4C A0 CD JMP $CDA0\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"Ro\u00dfm\u00f6ller-Changes\">Ro\u00dfm\u00f6ller Changes<\/h3>\n<p>But there are also sections in the emulator that had to be adapted for use in the CP\/M context:<\/p>\n<ul>\n<li>The memory model of the C64 CP\/M cartridge made the 8080 CPU see the machine&rsquo;s RAM moved up by $1000 &#8211; so the 8080 RST area and the 6502 zero page would not be at the same spot. The emulator also uses this layout, so every memory access has to go through an expensive 16 bit addidion. (Avoiding this addition would have been the better strategy &#8211; and ironically, Dann&rsquo;s original design document explains why he decided <em>not<\/em> to shift memory!)<\/li>\n<li>The interpreter was extended to special case &ldquo;LD ($CE00),A&rdquo; (which switches back to the 6502) and to support the &ldquo;LDIR&rdquo; instruction (a Z80 extension used by CP\/M), but it seems the people patching the emulator didn&rsquo;t understand the code well enough to work &ldquo;LDIR&rdquo; into the instruction decoder or put the address check into the &ldquo;LD (), A&rdquo; handler &#8211; instead, the interpreter loop checks for these instruction before the normal decode. (Ironically, the emulator already contains a special opcode to switch to 6502 mode, so it would have been easier to patch the code that switches modes.)<\/li>\n<li>\n<p>The following code increments the 8080 program counter in 45 cycles, while it could also have been done is as little as 6 cycles:<\/p>\n<pre><code>    ldx #pc - registers\n    ldy #const_one - registers\n    clc\n:   lda registers,x\n    adc registers,y\n    sta registers,x\n    iny\n    inx\n    tya\n    and #1\n    bne :- ; do it twice\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<p>Ro\u00dfm\u00f6ller did not make these modifications in source, but binary patched the original KIM-1 version: Changing the exact page alignment of the emulator would have required an extensive rework of the extremely optimized instruction decoder.<\/p>\n<p>But it doesn&rsquo;t mean the patches are done in an elegant way: They are very wasteful, weird&hellip; and just horrible. The following example stores a 16 bit register in memory at the address pointed to by PNT:<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<th>8080 Simulator for the 6502<\/th>\n<th>Ro\u00dfm\u00f6ller CP\/M Emulator<\/th>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<pre>017D RP\/MEM  LDYIM #$01    ; CLEAR INDEX\n017F RPLP    LDAZX REGS+1  ; GET NEXT RP DATA\n0181         STAIY PNT     ; STORE IN MEMORY\n0183         DEX\n0184         DEY\n0185         BEQ RPLP\n0187         RTS\n<\/pre>\n<\/td>\n<td>\n<pre>.,CB7D A0 01    LDY #$01\n<b>.,CB7F 20 44 CE JSR $CE44\n.,CB82 EA       NOP<\/b>\n.,CB83 CA       DEX\n.,CB84 88       DEY\n.,CB85 F0 F8    BEQ $CB7F\n.,CB87 60       RTS\n\n<b>.,CE44 20 C0 CE JSR $CEC0\n.,CE47 B5 36    LDA $36,X\n.,CE49 91 C1    STA ($C1),Y\n.,CE4B 60       RTS\n\n.,CEC0 08       PHP\n.,CEC1 20 20 CE JSR $CE20\n.,CEC4 28       PLP\n.,CEC5 60       RTS\n\n.,CE20 A5 4C    LDA $4C\n.,CE22 85 C1    STA $C1\n.,CE24 A5 4D    LDA $4D\n.,CE26 18       CLC\n.,CE27 69 10    ADC #$10\n.,CE29 85 C2    STA $C2\n.,CE2B 60       RTS<\/b>\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Since for CP\/M, memory is shifted by $1000, the Ro\u00dfm\u00f6ller version has to copy PNT into a temporary zero page location, add $1000 and use this one instead of PNT. The patch at $CE44 does the extra work. It calls the common routine $CEC0, which is supposed to make the copy + $1000 &#8211; and this function itself is a wrapper around a library function that saves the status bits for no reason. A more optimized version would have replaced all callers to $CB7D by code that does all this in one go. There was no reason to reuse logic; there are kilobytes of unused space!<\/p>\n<h3 id=\"Was-the-Emulator-Licensed?\">Was the Emulator Licensed?<\/h3>\n<p>Dann McCreary confirmed that Ro\u00dfm\u00f6ller never licensed the emulator from him:<\/p>\n<blockquote>\n<blockquote>\n<p>I don&rsquo;t have all the old records, but it seems likely that they bought a KIM-1 version directly from me at some point, or got it from one of my customers.<\/p>\n<\/blockquote>\n<\/blockquote>\n<p>After I commented that he was unlikely to sell any more copies of the KIM-1 version around the time the Ro\u00dfm\u00f6ller emulator was written, Dann wrote:<\/p>\n<blockquote>\n<blockquote>\n<p>I made random sales all around the globe&hellip; but you&rsquo;re probably right, 1987 sounds pretty late&hellip; Perhaps one of the Rossmuller principals had bought from me years earlier?<\/p>\n<\/blockquote>\n<\/blockquote>\n<p>Given that all Digital Research copyright messages were also completely removed from the product, it seems unlikely that the CP\/M part was licensed.<\/p>\n<h3 id=\"Conclusion\">Conclusion<\/h3>\n<p>Dann McCreary:<\/p>\n<blockquote>\n<blockquote>\n<p>Back in the day, I was asked repeatedly whether the simulator was suitable for running CP\/M, and my response invariably was that (in my opinion) it would run unacceptably slow. That is primarily why I never attempted the task myself. Of course, my code was completely optimized for space and not for speed&hellip; Those were the days of a 1.2K RAM space (KIM-1), or if you were lucky, 16K (Apple ][).<\/p>\n<\/blockquote>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>In this episode of computer archeology, we deconstruct a very interesting case of borrowing code from multiple places &#8211; but first try this D64 disk image with any Commodore 64 emulator or a real C64: Commodore 64 CP\/M Emulator The CP\/M operating system was the first home computer OS that ran on machines from many &#8230; <a title=\"Run CP\/M on your C64 &#8211; using Emulation!\" class=\"read-more\" href=\"https:\/\/www.pagetable.com\/?p=1315\" aria-label=\"Read more about Run CP\/M on your C64 &#8211; using Emulation!\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,41,8,22],"tags":[],"class_list":["post-1315","post","type-post","status-publish","format-standard","hentry","category-archeology","category-c64","category-commodore","category-operating-systems"],"_links":{"self":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/1315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1315"}],"version-history":[{"count":0,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/1315\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}