<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Chris, Paul<div class=""><br class=""></div><div class="">Good you mention the topic „errors". Here some errors I found and improvements I did to Project Oberon</div><div class=""><br class=""></div><div class="">1) Here my improved version of the procedure „opcode" in the disassembler „ORTool“:</div><div class=""><br class=""></div><div class=""><div class="">PROCEDURE opcode(w: LONGINT);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>VAR k, u, v, a, b, op: LONGINT;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>BEGIN</div><div class=""><span class="Apple-tab-span" style="white-space:pre">             </span>k :=  w DIV 40000000H MOD 4;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>u :=  w DIV 20000000H MOD 2;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>v :=  w DIV 10000000H MOD 2;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>a :=  w DIV   1000000H MOD 10H;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>b :=  w DIV     100000H MOD 10H;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>op := w DIV      10000H MOD 10H;</div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">          </span>IF (k = 0) OR (k = 1) THEN</font></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                           </span>Texts.WriteString(W, mnemo0[op]);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>IF u = 1 THEN Texts.Write(W, "'") END ;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>WriteReg(a);</div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                             </span>IF op = 0 THEN Texts.WriteString(W, "      ") ELSE WriteReg(b) END;       (* jr: MOV has no reg b *)</font></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>IF k = 0 THEN WriteReg(w MOD 10H)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>ELSE</div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                                     </span>w := w MOD 10000H; IF v = 1 THEN DEC(w, 10000H) END ;                (* jr: signed/unsigend handling *)</font></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                      </span>Texts.WriteInt(W, w, 7)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                           </span>END</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>ELSIF k = 2 THEN<span class="Apple-tab-span" style="white-space:pre">    </span>(*LDR/STR*)</div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                              </span>IF u = 1 THEN Texts.WriteString(W, "ST") ELSE Texts.WriteString(W, "LD") END ;</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>IF v = 1 THEN Texts.Write(W, "B") ELSE Texts.Write(W, "W") END;         (* jr: display Byte and Word access *)</font></div><div class=""><span class="Apple-tab-span" style="white-space:pre">                               </span>WriteReg(a); WriteReg(b);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>(* compiler assumes SIGNED offset. RISC5 extends "off" UNSIGNED to 24bit. Okay as memadr only uses 20 bit *)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                            </span>w := w MOD 100000H; IF w >= 80000H THEN DEC(w, 100000H) END;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                           </span>Texts.WriteInt(W, w, 8)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>ELSE<span class="Apple-tab-span" style="white-space:pre">        </span>(*Branch instr*)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>Texts.Write(W, "B");</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                            </span>IF v = 1 THEN Texts.Write(W, "L") END ;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>Texts.WriteString(W, mnemo1[a]);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>IF u = 0 THEN WriteReg(w MOD 10H)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                         </span>ELSE</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                      </span>(* compiler assumes SIGNED offset. With memory < 1MB and word offset, even w modulo 18 bit would be okay *)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                    </span>w := w MOD 100000H;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                       </span>IF w >= 80000H THEN DEC(w, 100000H) END ;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                                      </span>Texts.WriteInt(W, w, 8)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                           </span>END</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>END</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>END opcode;</div></div><div class=""><br class=""></div><div class="">- the signed/unsigned handling of immediate values in case 0 and 1 was wrong.</div><div class="">- I added the distinction of word/byte access in case 2. The opcodes are no longer LDR/STR but LDW/STW and LDB/STB.</div><div class="">- cosmetic: I skipped display of reg B on MOV as it’s not used.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">2) As Project Oberon is running on several platforms now (FPGA, Windows, MacOS), it is a little unfortunate that Project Oberon has no standardized definitions of the key codes for the up, left, right and down keys. As I like to move around the caret with my keyboard instead of the mouse I ended up with there different versions (one per platform) of procedure Write in „TextFrames.Mod“</div><div class="">As example, here the version of the procedure Write in TextFrames.Mod for the MacOS X emulator.</div><div class=""><br class=""></div><div class=""><div class="">PROCEDURE Write* (F: Frame; ch: CHAR; fnt: Fonts.Font; col, voff: INTEGER);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>VAR buf: Texts.Buffer;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>BEGIN (*F.hasCar*)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>IF ch = BS THEN<span class="Apple-tab-span" style="white-space:pre">     </span>(*backspace*)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>IF F.carloc.pos > <a href="http://f.org" class="">F.org</a> THEN</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                               </span>Texts.Delete(F.text, F.carloc.pos - 1, F.carloc.pos, DelBuf); SetCaret(F, F.carloc.pos - 1)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                       </span>END</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>ELSIF ch = 3X THEN (*!c<span class="Apple-tab-span" style="white-space:pre">     </span>copy*)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                    </span>IF F.hasSel THEN</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>NEW(TBuf); Texts.OpenBuf(TBuf); Texts.Save(F.text, F.selbeg.pos, F.selend.pos, TBuf)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                      </span>END</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>ELSIF ch = 16X THEN (*!v<span class="Apple-tab-span" style="white-space:pre">    </span>paste*)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                   </span>NEW(buf); Texts.OpenBuf(buf); Texts.Copy(TBuf, buf); Texts.Insert(F.text, F.carloc.pos, buf);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>SetCaret(F, F.carloc.pos + buf.len)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">               </span>ELSIF ch = 18X THEN (*!x,<span class="Apple-tab-span" style="white-space:pre">   </span>cut*)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>IF F.hasSel THEN</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                          </span>NEW(TBuf); Texts.OpenBuf(TBuf); Texts.Delete(F.text, F.selbeg.pos, F.selend.pos, TBuf)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                    </span>END</div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">              </span>ELSIF ch = 11X THEN (* left *)</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                      </span>IF F.carloc.pos > 0 THEN RemoveCaret(F); SetCaret(F, F.carloc.pos - 1) END</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">               </span>ELSIF ch = 12X THEN (* right *)</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                     </span>IF F.carloc.pos < F.text.len THEN RemoveCaret(F); SetCaret(F, F.carloc.pos + 1) END</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">              </span>ELSIF ch = 13X THEN (* up *)</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>RemoveCaret(F); SetCaret(F, Pos(F, F.X + F.carloc.x, F.Y + F.carloc.y + F.lsp))</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">             </span>ELSIF ch = 14X THEN (* down *)</font></div><div class=""><font color="#ff2600" class=""><span class="Apple-tab-span" style="white-space:pre">                      </span>RemoveCaret(F); SetCaret(F, Pos(F, F.X + F.carloc.x, F.Y + F.carloc.y - F.lsp))</font></div><div class=""><span class="Apple-tab-span" style="white-space:pre">              </span>ELSIF (20X <= ch) & (ch <= DEL) OR (ch = CR) OR (ch = TAB) THEN</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                 </span>KW.fnt := fnt; KW.col := col; KW.voff := voff; Texts.Write(KW, ch);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                       </span>Texts.Insert(F.text, F.carloc.pos, KW.buf);</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                       </span>SetCaret(F, F.carloc.pos + 1)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">             </span>END</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>END Write;</div><div class=""><br class=""></div><div class="">- As improvement, I see two possible solutions to this</div></div><div class="">  1) In the original Input.Mod there is an array for key code mapping. Define this as THE mapping all emulators have to follow it in their underlying keyboard routines.</div><div class="">  2) add constant definitions in Input.Mod (either fix or varying per platform) for the control keys BS / LF / DEL / CR / TAB / HT / ESC / Setstar / up / down / leftt / right. These constants could then be used in upper layer modules like TextFrames.Mod, Oberon.Mod or ORS.Mod</div><div class=""> I personally would prefer 2)</div><div class=""><br class=""></div><div class="">br</div><div class="">Jörg</div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">Am 12.01.2016 um 09:02 schrieb Chris Burrows <<a href="mailto:chris@cfbsoftware.com" class="">chris@cfbsoftware.com</a>>:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" class="">He releases a compiler and doesn't offer an error reporting system. <br class=""></blockquote><br class="">Personally I prefer Wirth spends his time working on what he is good at i.e.<br class="">developing the compiler, Verilog sources and Lola and let others like myself<br class="">who are not so skilled in those areas to look after handling error reports,<br class="">support issues etc. <br class=""><br class="">It is immportant to note that the well-documented, high quality, Project<br class="">Oberon system is not your typical type of open source system. Unfortunately<br class="">all too often all you get is pre-alpha quality source code that the<br class="">developer (or more accurately 'hacker' - in the traditional sense of the<br class="">word) cannot be bothered to test or document. Given the choice of the<br class="">Cathedral or the Bizarre (sic) I'd go for the Cathedral approach any day.<br class=""><br class="">In my experience in the last eight years of working with Wirth's Oberon-07<br class="">compilers bugs are as scarce as hen's teeth. I have always found him (and<br class="">Paul) to be very communicative and generous with their time whenever I have<br class="">contacted them. <br class=""><br class="">However, in the unlikely event that you think you have discovered a bug and<br class="">you prefer to use a different form of communication than email you are<br class="">welcome to report it on the Astrobe forum and I'll see what I can do to<br class="">help:<br class=""><br class=""><a href="http://www.astrobe.com/forum/viewtopic.php?f=5&t=452" class="">http://www.astrobe.com/forum/viewtopic.php?f=5&t=452</a><br class=""><br class="">The last reported (and fixed) bug in our Cortex-M3/M4 Oberon-07 compilers<br class="">was in June last year. As far as I remember only three bugs have been<br class="">reported in this ETH mailing list since Project Oberon was released a couple<br class="">of years ago and they have all since been fixed. Hence it would be difficult<br class="">to justify the use of a formalised bug-reporting system. Chances are that<br class="">such a system would be more complex than Project Oberon!<br class=""><br class="">There is no comparison between Oberon and Delphi when it comes to quality. I<br class="">have been using Delphi since v1.0 in Feb 199S. The initial release was very<br class="">good but went rapidly downhill from about v4 onwards. Since then Delphi<br class="">typically has had something like 500 bugs active at any one time so Borland<br class="">/ CodeGear / Embarcadero / Idera would not be able to manage them without a<br class="">formalised system, <br class=""><br class="">Regards,<br class="">Chris Burrows <br class=""><br class="">CFB Software<br class="">http://www.astrobe.com<br class=""><br class=""><br class=""><br class=""><br class="">--<br class="">Oberon@lists.inf.ethz.ch mailing list for ETH Oberon and related systems<br class="">https://lists.inf.ethz.ch/mailman/listinfo/oberon<br class=""></div></div></blockquote></div><br class=""></div></body></html>