# Delphi で覚える SC61860 --- tags: Delphi Pascal ポケコン objectpascal created_at: 2022-05-16 updated_at: 2022-12-30 --- # はじめに その昔 PC-1246 を買ったので SC61860 のマシン語にとんとご縁のなかった私がひょんな事で PC-1245 を入手したばっかりに今頃になって SC61860 のマシン語でプログラムを書きたくて (以下略)。 ![image.png](./images/ff6874e0-5b94-444c-4dc1-384f83c3bc8f.png) あ、`SC61860` というのは SHARP の昔のポケコンの CPU の事です。 # どうやって覚えるか 実機で覚えようとすると暴走で再入力とかやってられないのでエミュレータ的な何かを作ればいいんじゃね?と思い立ち Delphi で 作ってみる事にした。ちょっと大きめの BrainFuck ですな。 ## ソース SC61860 のマシン語を覚えられるくらいの内容。 ```pascal:uSC61860.pas unit uSC61860; interface uses System.SysUtils, System.Classes; type TSC61860 = record private function GetData: UInt8; function GetMem(Index: UInt16): UInt8; procedure SetMem(Index: UInt16; const Value: UInt8); public Memory: array [$0000..$FFFF] of UInt8; H: UInt8; // Internal Aux. Register P: UInt8; // Internal RAM Pointer Q: UInt8; // Internal RAM Pointer R: UInt8; // Internal RAM Pointer (Stack Pointer) S: UInt8; // Unused C: Boolean; // Carry flag D: UInt8; // Working Register Z: Boolean; // Zero flag Port_IA: UInt8; Port_IB: UInt8; Port_Control: UInt8; Port_FO: UInt8; CaseCnt: UInt8; RamStart: UInt16; RamEnd: UInt16; VramStart: UInt16; VramEnd: UInt16; procedure Init; procedure LoadMemory(const Filename: string; StartAddr: uInt16 = $0000; EndAddr: uInt16 = $FFFF); procedure SaveMemory(const Filename: string; StartAddr: uInt16 = $0000; EndAddr: uInt16 = $FFFF); procedure Execute(Address: UInt16 = $0000); property Data: UInt8 read GetData; property RAM[Index: UInt16]: UInt8 read GetMem write SetMem; case Boolean of False: ( PC: UInt16; // Program Counter DP: UInt16; // Data pointer I: UInt8; // Index Counter J: UInt8; // Index Counter A: UInt8; // Accumulator B: UInt8; // Secondary Accumulator X: UInt16; // 16 bit RAM pointer (XL = InternalRAM[$04], XH = InternalRAM[$05]) Y: UInt16; // 16 bit RAM pointer (YL = InternalRAM[$06], LH = InternalRAM[$07]) K: UInt8; // General Purpose Pointer L: UInt8; // General Purpose Pointer M: UInt8; // General Purpose Pointer N: UInt8; // General Purpose Pointer IR: array [$0C..$5B] of UInt8; // Internal RAM - Stack IA: UInt8; // Port IA IB: UInt8; // Port IB FO: UInt8; // Port FO OUTC: UInt8; // Control Port ); True: ( PCL: UInt8; PCH: UInt8; DPL: UInt8; DPH: UInt8; InternalRAM: array [$00..$5F] of UInt8 ); end; var SC: TSC61860; implementation { TSC61860 } procedure TSC61860.Execute(Address: UInt16 = $0000); var MCode: UInt8; v: UInt8; w: UInt16; x1, x2: UInt32; begin if Address > 0 then PC := Address; MCode := Data; case MCode of $00: // LII n begin Inc(PC); I := Data; end; $01: // LIJ n begin Inc(PC); J := Data; end; $02: // LIA n begin Inc(PC); A := Data; end; $03: // LIB n begin Inc(PC); B := Data; end; $04: // IX begin Q := $00; // need debug Inc(X); DP := X; end; $05: // DX begin Q := $00; // need debug Dec(X); DP := X; end; $06: // IY begin Q := $00; // need debug Inc(Y); DP := Y; end; $07: // DY begin Q := $00; // need debug Dec(Y); DP := Y; end; $08: // MVW begin for var Cnt := 0 to I do InternalRAM[P + Cnt] := InternalRAM[Q + Cnt]; Inc(P, I + 1); Inc(Q, I + 1); end; $09: // EXW begin for var Cnt := 0 to I do begin v := InternalRAM[P + Cnt]; InternalRAM[P + Cnt] := InternalRAM[Q + Cnt]; InternalRAM[Q + Cnt] := v; end; Inc(P, I + 1); Inc(Q, I + 1); end; $0A: // MVB begin for var Cnt := 0 to J do InternalRAM[P + Cnt] := InternalRAM[Q + Cnt]; Inc(P, J + 1); Inc(Q, J + 1); end; $0B: // EXB begin for var Cnt := 0 to J do begin v := InternalRAM[P + Cnt]; InternalRAM[P + Cnt] := InternalRAM[Q + Cnt]; InternalRAM[Q + Cnt] := v; end; Inc(P, J + 1); Inc(Q, J + 1); end; $0C: // ADN begin var Num1: UInt8; var Num2: UInt8 := (A shr 4) * 10 + (A and $0F); var Num3: UInt8; for var Cnt:=0 to I do begin Num1 := (InternalRAM[P-Cnt] shr 4) * 10 + (InternalRAM[P-Cnt] and $0F); Num3 := Num1 + Num2; Num2 := Num3 div 100; Num3 := Num3 mod 100; InternalRAM[P-Cnt] := ((Num3 div 10) shl 4) or (Num3 mod 10); end; C := Num2 > 0; Z := True; for var Cnt:=0 to I do begin if InternalRAM[Cnt] > 0 then begin Z := False; Break; end; end; end; $0D: // SBN begin var Borrow: Boolean := False; var Num1: UInt8; var Num2: UInt8 := (A shr 4) * 10 + (A and $0F); var Num3: UInt8; for var Cnt:=0 to I do begin Num1 := (InternalRAM[P-Cnt] shr 4) * 10 + (InternalRAM[P-Cnt] and $0F); if Borrow then Dec(Num1); Borrow := Num2 > Num1; if Borrow then Num1 := Num1 + 100; Num3 := Num1 - Num2; Num2 := Num3 div 100; Num3 := Num3 mod 100; InternalRAM[P-Cnt] := ((Num3 div 10) shl 4) or (Num3 mod 10); end; C := Borrow; Z := True; for var Cnt:=0 to I do begin if InternalRAM[Cnt] > 0 then begin Z := False; Break; end; end; end; $0E: // ADW begin var Carry: Boolean := False; var Num1: UInt8; var Num2: UInt8; var Num3: UInt8; for var Cnt:=0 to I do begin Num1 := (InternalRAM[P-Cnt] shr 4) * 10 + (InternalRAM[P-Cnt] and $0F); Num2 := (InternalRAM[Q-Cnt] shr 4) * 10 + (InternalRAM[Q-Cnt] and $0F); Num3 := Num1 + Num2; if Carry then Inc(Num3); Num2 := Num3 div 100; Carry := Num2 > 0; Num3 := Num3 mod 100; InternalRAM[P-Cnt] := ((Num3 div 10) shl 4) or (Num3 mod 10); end; Z := True; for var Cnt:=0 to I do begin if InternalRAM[Cnt] > 0 then begin Z := False; Break; end; end; end; $0F: // SBW begin var Borrow: Boolean := False; var Num1: UInt8; var Num2: UInt8; var Num3: UInt8; for var Cnt:=0 to I do begin Num1 := (InternalRAM[P-Cnt] shr 4) * 10 + (InternalRAM[P-Cnt] and $0F); Num2 := (InternalRAM[Q-Cnt] shr 4) * 10 + (InternalRAM[Q-Cnt] and $0F); if Borrow then Dec(Num1); Borrow := Num2 > Num1; if Borrow then Num1 := Num1 + 100; Num3 := Num1 - Num2; InternalRAM[P-Cnt] := ((Num3 div 10) shl 4) or (Num3 mod 10); end; Z := True; for var Cnt:=0 to I do begin if InternalRAM[Cnt] > 0 then begin Z := False; Break; end; end; end; $10: // LIDP n m begin Inc(PC); w := Data shl 8; Inc(PC); w := w + Data; DP := w; end; $11: // LIDL n begin Inc(PC); DP := (DP and $FF) or Data; end; $12: // LIP n begin Inc(PC); P := (P and $80) or (Data and $7F); end; $13: // LIQ n begin Inc(PC); Q := (Q and $80) or (Data and $7F); end; $14: // ADB begin x1 := (B shl 8) or A; x2 := (InternalRAM[P + 1] shl 8) or InternalRAM[P]; x1 := x2 + x1; C := x1 > $FFFF; Z := x1 = 0; InternalRAM[P + 1] := (x1 and $FFFF) shr 8; InternalRAM[P + 0] := (x1 and $00FF); end; $15: // SBB begin x1 := (B shl 8) or A; x2 := (InternalRAM[P + 1] shl 8) or InternalRAM[P]; x1 := x2 - x1; C := x1 > $FFFF; // need debug Z := x1 = 0; InternalRAM[P + 1] := (x1 and $FFFF) shr 8; InternalRAM[P + 0] := (x1 and $00FF); end; $16: // (N/A) HALT ; $17: // (N/A) HALT ; $18: // MVWD begin for var Cnt := 0 to I do InternalRAM[P + Cnt] := Memory[DP + Cnt]; Inc(DP, I); Inc(P, I + 1); end; $19: // EXWD begin for var Cnt := 0 to I do begin v := InternalRAM[P + Cnt]; InternalRAM[P + Cnt] := Memory[DP + Cnt]; RAM[DP + Cnt] := v; end; Inc(DP, I); Inc(P, I + 1); end; $1A: // MVBD begin for var Cnt := 0 to J do InternalRAM[P + Cnt] := Memory[DP + Cnt]; DP := DP + J; P := P + J + 1; end; $1B: // EXBD begin for var Cnt := 0 to J do begin v := InternalRAM[P + Cnt]; InternalRAM[P + Cnt] := Memory[DP + Cnt]; RAM[DP + Cnt] := v; end; end; $1C: // SRW begin var v2: UInt8; for var Cnt := 0 to I - 1 do begin if Cnt < (I - 1) then v2 := (InternalRAM[P + Cnt + 1] shl 4) else v2 := 0; InternalRAM[P + Cnt] := (InternalRAM[P + Cnt] shr 4) or v2; end; end; $1D: // SLW begin var v2: UInt8; for var Cnt := 0 to I - 1 do begin if Cnt < (I - 1) then v2 := (InternalRAM[P + Cnt + 1] shr 4) else v2 := 0; InternalRAM[P + Cnt] := (InternalRAM[P + Cnt] shl 4) or v2; end; end; $1E: // FILM begin for var Cnt := 0 to I do InternalRAM[P + Cnt] := A; Inc(P, I + 1); end; $1F: // FILD begin for var Cnt := 0 to I do RAM[DP + Cnt] := A; Inc(DP, I); end; $20: // LDP begin A := P; end; $21: // LDQ begin A := Q; end; $22: // LDR begin A := R; end; $23: // (N/A) CLRA begin A := $00; end; $24: // IXL begin Q := $00; // need debug Inc(X); DP := X; A := Memory[DP]; end; $25: // DXL begin Q := $00; // need debug Dec(X); DP := X; A := Memory[DP]; end; $26: // IYS begin Q := $00; // need debug Inc(Y); DP := Y; RAM[DP] := A; end; $27: // DYS begin Q := $00; // need debug Dec(Y); DP := Y; RAM[DP] := A; end; $28: // JRNZP n begin Inc(PC); if not Z then Inc(PC, Data - 1); end; $29: // JRNZM n begin Inc(PC); if not Z then Dec(PC, Data + 1); end; $2A: // JRNCP n begin Inc(PC); if not C then Inc(PC, Data - 1); end; $2B: // JRNCM n begin Inc(PC); if not C then Dec(PC, Data + 1); end; $2C: // JRP n begin Inc(PC); Inc(PC, Data - 1); end; $2D: // JRM n begin Inc(PC); Dec(PC, Data + 1); end; $2E: // (N/A) HALT ; $2F: // LOOP n begin Inc(PC); Dec(InternalRAM[R]); C := InternalRAM[R] = $FF; Z := InternalRAM[R] = $00; if not C then Inc(PC, Data - 1); // -1 end; $30: // STP begin P := A; end; $31: // STQ begin Q := A; end; $32: // STR begin R := A; end; $33: // (N/A) NOPT ; $34: // PUSH begin Dec(R); InternalRAM[R] := A; end; $35: // RST / MVWP (未定義命令) begin w := (B shl 8) or A; for var Cnt := 0 to I do InternalRAM[P + Cnt] := Memory[w + Cnt]; end; $36: // (N/A) HALT ; $37: // RTN begin PC := (InternalRAM[R+1] shl 8) + InternalRAM[R] -1; // -1 Inc(R, 2); end; $38: // JRZP n begin Inc(PC); if Z then Inc(PC, Data - 1); end; $39: // JRZM n begin Inc(PC); if Z then Dec(PC, Data + 1); end; $3A: // JRCP n begin Inc(PC); if C then Inc(PC, Data - 1); end; $3B: // JRCM n begin Inc(PC); if C then Dec(PC, Data + 1); end; $3C: // (N/A) HALT ; $3D: // (N/A) HALT ; $3E: // (N/A) HALT ; $3F: // (N/A) HALT ; $40: // INCI begin w := I + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug I := w and $FF; end; $41: // DECI begin w := I - 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug I := w and $FF; end; $42: // INCA begin w := A + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug A := w and $FF; end; $43: // DECA begin w := A - 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug A := w and $FF; end; $44: // ADM begin w := InternalRAM[P] + A; C := w > $FF; // need debug Z := w = $00; InternalRAM[P] := w and $FF; end; $45: // SBM begin w := InternalRAM[P] - A; C := w > $FF; // need debug Z := w = $00; InternalRAM[P] := w and $FF; end; $46: // ANMA begin w := InternalRAM[P] and A; Z := w = $00; InternalRAM[P] := w and $FF; end; $47: // ORMA begin w := InternalRAM[P] or A; Z := w = $00; InternalRAM[P] := w and $FF; end; $48: // INCK begin w := K + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug K := w and $FF; end; $49: // DECK begin w := K - 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug K := w and $FF; end; $4A: // INCM begin w := M + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug M := w and $FF; end; $4B: // DECM begin w := M + 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug M := w and $FF; end; $4C: // INA begin A := Port_IA; end; $4D: // NOPW begin end; $4E: // WAIT n begin Inc(PC); end; $4F: // CUP / IPXL begin // Not implemented yet end; $50: // INCP begin Inc(P); end; $51: // DECP begin Dec(P); end; $52: // STD begin RAM[DP] := A; end; $53: // MVDM begin RAM[DP] := InternalRAM[P]; end; $54: // MVMP (READM) begin InternalRAM[P] := Memory[PC+1]; end; $55: // MVMD begin InternalRAM[P] := Memory[DP]; end; $56: // LDPC (READ) begin A := Memory[PC+1]; end; $57: // LDD begin A := Memory[DP]; end; $58: // SWP begin v := (A and $F0) shr 4; A := (A shl 4) or v; end; $59: // LDM begin A := InternalRAM[P]; end; $5A: // SL begin A := (A shl 1) or Ord(C); end; $5B: // POP begin A := InternalRAM[R]; Inc(R); end; $5C: // (N/A) HALT ; $5D: // OUTA begin Port_IA := IA; end; $5E: // (N/A) HALT ; $5F: // OUTF begin Port_FO := FO; end; $60: // ANIM n begin Inc(PC); w := InternalRAM[P] and Data; Z := w = $00; InternalRAM[P] := w and $FF; end; $61: // ORIM n begin Inc(PC); w := InternalRAM[P] or Data; Z := w = $00; InternalRAM[P] := w and $FF; end; $62: // TSIM n begin Inc(PC); Z := (InternalRAM[P] and Data) = 0; end; $63: // CPIM n begin Inc(PC); v := Data; if InternalRAM[P] > v then begin C := False; Z := False; end else if InternalRAM[P] < v then begin C := True; Z := False; end else begin C := False; Z := True; end; end; $64: // ANIA n begin Inc(PC); w := A and Data; Z := w = $00; A := w and $FF; end; $65: // ORIA n begin Inc(PC); w := A or Data; Z := w = $00; A := w and $FF; end; $66: // TSIA n begin Inc(PC); Z := (A and Data) = 0; end; $67: // CPIA n begin Inc(PC); v := Data; if A > v then begin C := False; Z := False; end else if A < v then begin C := True; Z := False; end else begin C := False; Z := True; end; end; $68: // (N/A) NOPT ; $69: // CASE2 (JST) begin w := 0; for var i:=0 to CaseCnt-1 do begin Inc(PC); v := Data; if A = v then begin Inc(PC); w := Data shl 8; Inc(PC); w := w or Data; PC := w - 1; // -1 Break; end; end; if w = 0 then begin Inc(PC); w := Data shl 8; Inc(PC); w := w or Data; PC := w - 1; end; end; $6A: // (N/A) NOPT ; $6B: // TEST n begin Inc(PC); // Not implemented yet end; $6C: // (N/A) HALT ; $6D: // (N/A) HALT ; $6E: // (N/A) HALT ; $6F: // CDN / IPXH begin // Not implemented yet end; $70: // ADIM n begin Inc(PC); w := InternalRAM[P] + Data; C := w > $FF; // need debug Z := w = $00; InternalRAM[P] := w and $FF; end; $71: // SBIM n begin Inc(PC); w := InternalRAM[P] - Data; C := w > $FF; // need debug Z := w = $00; InternalRAM[P] := w and $FF; end; $72: // (N/A) RZ begin Z := False; end; $73: // (N/A) RZ begin Z := False; end; $74: // ADIA n begin Inc(PC); w := A + Data; C := w > $FF; // need debug Z := w = $00; A := w and $FF; end; $75: // SBIA n begin Inc(PC); w := A - Data; C := w > $FF; // need debug Z := w = $00; A := w and $FF; end; $76: // (N/A) RZ begin Z := False; end; $77: // (N/A) RZ begin Z := False; end; $78: // CALL n m begin w := PC + 3; InternalRAM[R-1] := w shr 8; InternalRAM[R-2] := w and $FF00; Dec(R, 2); Inc(PC); w := Data shl 8; Inc(PC); w := w + Data; PC := w - 1; // -1 end; $79: // JP n m begin Inc(PC); w := Data shl 8; Inc(PC); w := w or Data; PC := w - 1; end; $7A: // CASE1 (SETT) l n m begin Inc(PC); CaseCnt := Data; Inc(PC); InternalRAM[R-1] := Data; Inc(PC); InternalRAM[R-2] := Data; Dec(R, 2); end; $7B: // (N/A) HALT ; $7C: // JPNZ n m begin Inc(PC); w := Data shl 8; Inc(PC); w := w or Data; if not Z then PC := w - 1; end; $7D: // JPNC n m begin Inc(PC); w := Data shl 8; Inc(PC); w := w or Data; if not C then PC := w - 1; end; $7E: // JPZ n m begin Inc(PC); w := Data shl 8; Inc(PC); w := w or Data; if Z then PC := w - 1; end; $7F: // JPC n m begin Inc(PC); w := Data shl 8; Inc(PC); w := w or Data; if C then PC := w - 1; end; $80..$BF: // LP begin P := Data - $80; end; $C0: // INCJ begin w := J + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug J := w and $FF; end; $C1: // DECJ begin w := J - 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug J := w and $FF; end; $C2: // INCB begin w := B + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug B := w and $FF; end; $C3: // DECB begin w := B - 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug B := w and $FF; end; $C4: // ADCM begin w := InternalRAM[P] + A + Ord(C); C := w > $FF; Z := w = $00; InternalRAM[P] := w and $FF; end; $C5: // SBCM begin w := InternalRAM[P] - A - Ord(C); C := w > $FF; // need debug Z := w = $00; InternalRAM[P] := w and $FF; end; $C6: // TSMA (未定義命令) begin Z := InternalRAM[P] = A; end; $C7: // CPMA begin if InternalRAM[P] > A then begin C := False; Z := False; end else if InternalRAM[P] < A then begin C := True; Z := False; end else begin C := False; Z := True; end; end; $C8: // INCL begin w := L + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug L := w and $FF; end; $C9: // DECL begin w := L - 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug L := w and $FF; end; $CA: // INCN begin w := N + 1; C := w > $FF; Z := w = $00; Q := $00; // need debug N := w and $FF; end; $CB: // DECN begin w := N - 1; C := w > $FF; // need debug Z := w = $00; Q := $00; // need debug N := w and $FF; end; $CC: // INB begin A := Port_IB; end; $CD: // (N/A) NOPW ; $CE: // NOPT begin end; $CF: // (N/A) HALT ; $D0: // SC begin C := True; Z := True; end; $D1: // RC begin C := False; Z := True; end; $D2: // SR begin C := Odd(A); A := A shr 1; end; $D3: // WRIT (NOPW) begin end; $D4: // ANID n begin Inc(PC); w := Memory[DP] and Data; Z := w = $00; RAM[DP] := w and $FF; end; $D5: // ORID n begin Inc(PC); w := Memory[DP] or Data; Z := w = $00; RAM[DP] := w and $FF; end; $D6: // TSID n begin Inc(PC); Z := (Memory[DP] and Data) = 0; end; $D7: // CPID n begin Inc(PC); // Not implemented yet end; $D8: // LEAVE begin InternalRAM[R] := 0; end; $D9: // (N/A) NOPW ; $DA: // EXAB begin v := A; A := B; B := v; end; $DB: // EXAM begin v := A; A := InternalRAM[P]; InternalRAM[P] := v; end; $DC: // (N/A) HALT ; $DD: // OUTB begin Port_IB := IB; end; $DE: // (N/A) HALT ; $DF: // OUTC begin Port_Control := OUTC; end; $E0..$FF: // CAL n begin w := PC + 2; InternalRAM[R-1] := w shr 8; InternalRAM[R-2] := w and $FF00; Dec(R, 2); w := (Data - $E0) shl 8; Inc(PC); w := w + Data; PC := w - 1; // -1 end; end; Inc(PC); end; function TSC61860.GetData: UInt8; begin result := Memory[PC]; end; function TSC61860.GetMem(Index: UInt16): UInt8; begin result := Memory[Index]; end; procedure TSC61860.SetMem(Index: UInt16; const Value: UInt8); begin if ((Index >= RamStart ) and (Index <= RamEnd )) or ((Index >= VramStart) and (Index <= VramEnd)) then Memory[Index] := Value; end; procedure TSC61860.Init; begin Self := Default(TSC61860); R := $5B; RamStart := $C000; // PC-1245/50 //RamStart := $B800; // PC-1251 //RamStart := $A000; // PC-1255 //RamStart := $5800; // PC-1260 //RamStart := $4000; // PC-1261/62 //RamStart := $6000; // PC-1350 RamEnd := $C7FF; // PC-1245/5x //RamEnd := $67FF; // PC-126x //RamEnd := $6FFF; // PC-1350 VramStart := $F800; // PC-1245/5x //VramStart := $2000; // PC-126x //VramStart := $7000; // PC-1350 VramEnd := $F8BF; // PC-1245/5x //VramEnd := $38BF; // PC-126x //VramEnd := $7FFF; // PC-1350 end; procedure TSC61860.LoadMemory(const Filename: string; StartAddr, EndAddr: uInt16); begin var MS := TMemoryStream.Create; try MS.LoadFromFile(Filename); MS.Read(Memory[StartAddr], Succ(EndAddr - StartAddr)); finally MS.Free; end; end; procedure TSC61860.SaveMemory(const Filename: string; StartAddr, EndAddr: uInt16); begin var MS := TMemoryStream.Create; try MS.Write(Memory[StartAddr], Succ(EndAddr - StartAddr)); MS.SaveToFile(Filename); finally MS.Free; end; end; end. ``` キャリーフラグとゼロフラグが適当ではないかもしれない。実機と異なる挙動があったら都度修正する事にする。 ## 使い方 Delphi プロジェクトの **uses** に `uSC61860` を追加して、 ```pascal uses ..., uSC61860; ``` 適当な場所でコードを書く。 ```pascal procedure TForm1.Button1Click(Sender: TObject); begin SC.Init; //SC.LoadRom('pc1245mem.bin'); // Start Address 0x0000 Memo1.Lines.Clear; SC.P := $3F; SC.Q := $3C; SC.I := $02; SC.InternalRAM[$3A] := $01; SC.InternalRAM[$3B] := $23; SC.InternalRAM[$3C] := $45; SC.InternalRAM[$3D] := $45; SC.InternalRAM[$3E] := $67; SC.InternalRAM[$3F] := $89; SC.RAM[$C400] := $0F; SC.Execute($C400); Memo1.Lines.Add(Format('3D=%.2x', [SC.InternalRAM[$3D]])); Memo1.Lines.Add(Format('3E=%.2x', [SC.InternalRAM[$3E]])); Memo1.Lines.Add(Format('3F=%.2x', [SC.InternalRAM[$3F]])); ... end; ``` `SC.Execute()` を実行する度に 1 命令分逐次実行される。 # おわりに コードを書いたので、命令セットにどんなものがあるのかはもう覚えた (w ![image.png](./images/f933b2c4-0ad0-c5b7-214e-0ee67424c237.png) ![image.png](./images/55ca4a0d-b87f-771e-b6a1-4ff433225e58.png) 先述のコードを元に、**トレーナー兼簡易アセンブラ** を[作成中](https://ht-deko.com/pokecom/software.html#02)。 **See also:** - [Pocket Computer PC-1350 Machine Language Reference Manual (yumpu.com)](https://www.yumpu.com/xx/document/read/4129074/pc1350-ml-ref-manual) - [Pocket Computer PC-1350 Machine Language Reference Manual (PockEmul)](https://pockemul.com/wp-content/uploads/2022/12/PC1350_ML_EN.pdf) - [SC61860 (aka ESR-H) Instruction Set (GitHub)](https://github.com/utz82/SC61860-Instruction-Set) - [PC-1245 (JP3TLC's homepage)](http://jp3tlc.com/pc12/pc12inst.shtml) - [PC-1251 CPU SC61860 (Enri's Home PAGE)](http://www43.tok2.com/home/cmpslv/Pc1251/Enr51cpu.htm) - [SHARP PC-1245/50/51/55 の使い方 (ht-deko.com)](https://ht-deko.com/pc1245/)