言わずと知れたApple社の代表的なマシン「Apple][」です。1977年に発売され、モデルチェンジを繰り返しながらも1993年まで生産し続けられたロングセラー機です。この頃の米国製のマイコンでは、他にコモドールのPETやTandyのTRS-80などがありました。国産ではMZ80やPC-8001、BasicMaster、FM-8などが少し遅れて出始めたと思います。
初期の頃は東レが代理店として日本向けモデルの"j-plus"を国内で販売していました(Macintoshはキャノン販売が扱い、後にアップルの日本法人が設立されました)。当時、私はこのApple ][ j-plusを所有していました。驚くことに本体やマニュアルとともに回路図まで同梱されていたのですが、残念ながら今では実機も手放してしまいました。しかし、あの筐体のデザインやロゴは今でも忘れられない斬新なものだったと思います。
BASICやアセンブラを覚え、多少なりともプログラムが組めるようになったのも、Appleのお陰でした。
しかし、三つ子の魂百までとでも言いましょうか、何を血迷ったか1984年製のIIeの中古を手に入れ、数十年ぶりの再会を果たしました。
Apple][plusのROMの一部を書き換えてカタカナが表示できるようにローカライズした日本向けのバージョン(他にも欧州向けのeuro-plusというのもあったらしい)。キーの手前側の側面にカタカナが刻印されていた。元になったplusはApple][のロゴに緑色で"plus"書き添えられていたが、j-plusは赤色で書かれていた。当時、これにDISK][一台を付けて使っていた。
とにかく熱暴走に悩まされたのを覚えているw 家の場合は暴走すると電源ランプがチカチカ点滅してフリーズしてしまった。本体向かって左側に電源ユニットがあったのだが、ここに取り付けるサードパーティ製の外部ファンが売られていた程だった。よほど電源ユニットが弱かったのだと思う。で、暴走しないように夏場は上部の蓋を開けっ放しにして、小型の扇風機で本体を冷却しながら使ったものだ。
ソフトもハードも他の国産マシンに比べてとにかく高価で、ゲーム一本が普通に1万円とかしたので余程の余裕がない限り維持するのが大変なマシンでもあった(ま、輸入品が多かったから仕方のない面もあったけど)。折角DISK][があったのに、安いカセット版のゲームしか買えなかった。それでも6502でアセンブラを覚えたり、いろいろ学習させて貰ったと思う。
勿論、所有なんてしたことはないw しかし、当時][の後継機が登場すると聞いたので、拙い英語でAppleに手紙を書いたら、何と後日カタログが送られてきた。遠い日本の少年からの希望にわざわざ応えてくれるとは、まだApple社も大らかな時代だったのかもしれない。結局///は大ゴケ、Lisaもパッとせず(200万くらいした)、初代Macが発表されて間もなくジョブズが追い出されてしまったのは周知の通りだ。
キャノンが代理店の頃のMacはとても高価で、plusでも40万円くらいしていたと思う。LaserWriterだけで100万円した時代。そこ頃、20万円くらいで並行輸入版のplusがあったので、そちらに飛びついた。これにサードパーティ製の内蔵HDDを入れて(と言っても、基盤のSCSI端子に強引に取り付ける危ない代物だったけど)使っていた。当然、Mac Openerという工具も手に入れていた。漢字Talkが6の頃の話だ。唯一、購入したソフトはThinkCだったと思う。ま、基本的にはゲームには向いてないマシンだったし、付属のソフトでもそこそこ楽しめた。
名前を失念してしまったが(追記:APDAだったw Apple Programmer's Developer's Association)、当時、今で言うADCのような公式の組織があり、会員になると会報(というかカタログ冊子)が送られて来て開発者向けの"AS IS"な各種資料や書籍を有料で入手することができた。まだ珍しかったGUI向けのプログラミングなど、日本語の資料も僅かだったのでバイブルとも言えるInsideMacintoshという公式の開発者用の書籍が頼りだった。これについてはI〜V巻くらいあったと思うが、日本語版も存在した。高価で買えなかったが、何と地元の図書館に置いてあったので借りて読んではThinkCでポチポチとプログラムをしていた。何で地方の図書館にこんな書籍があったのかは謎だが、他に借りる人もいなかったので自分専用状態になっていたw 日本語版は百科事典並みに分厚かったので、持って帰るのが大変だったw
このInsideMacintoshであるが、頻繁に改訂が行われたので前述の会員に有料で差分だけが送られてくるサービスがあった(勿論、英語版のみではあるが)。よく、外国のマニュアルは製本しないでバインダーのようなものに閉じているものがあるが、この資料もバインダー式になっていて改訂される毎に差分のページだけが封筒で送られてくるというエコなシステムになっていた(今ならネットがあるのでこんな煩わしいことはないだろうけど)。今でもPDFで読めるようだ。
初期のMacはモトローラのMC680x0系が採用されていたが、その後PowerPCへと変更された。そこからジョブスが戻るまでAppleは長らく低迷し、かなり廉価なMacも登場したり互換機も出たりしていたが、その頃のMacは一台も所有することはなかった。Intel Macが登場するまでは、、、w
社名から"Computer"が消え去り、iPodやiPhoneの成功もあってコンピュータに無縁な人にも"Apple"社という名が広まった(70年代後半のあの頃には想像もつかなかった)。
Apple][はCPUに6502(1MHz)を搭載した8bit機です。そのメモリマップは下図のような構成になっていました:
メモリが16K/32K/48KBのモデルがありました。後期の//eや//c、GSなどはもっと大量のメモリを搭載できたようですが、これらのモデルは日本ではあまり馴染みがなかったかもしれません(//cはあったかな?)。
初期のApple][にはWoz謹製の整数BASIC(6K-BASIC)が載っていました。後にApplesoftと呼ばれる浮動小数の扱える10K-BASICが搭載されるようになります。plus/j-plusは、10K-BASIC搭載でしたが、整数BASIC ROMカードを刺すと整数BASICも使えました。このカードには赤いスイッチが付いており、電源を入れる前に予めどちらのROMから立ち上げるか設定しておく固定式だったと思います(私はこのカードを付けていたのですが、もう遠い記憶過ぎてうろ覚え)。またランゲージカードと呼ばれる16KBの拡張RAMを刺して、DISKから読み込ませることで実行中でも動的に切り替え(INT/FPコマンド)て使う事も出来ました。このカードはBASICだけでなく、PASCALなども読み込ませて使う事ができました。
6K-BASICのROMにはミニアセンブラが内蔵されていたので、簡単なマシン語なら、これで書くことも可能でした(当然、10K-BASICからは使えません)。モニタからF666G($F666番地にジャンプ)するとプロンプトが"!"に変わってアセンブラコードを打ち込めるようになります:
ちなみにミニアセンブラからモニタに戻るにはFF69Gです:
j-plusでは10K-BASIC ROM部分はplusと同じでしたが、モニターROM(F8)や表示するキャラクターデータROM(一部かカタカナになっていた)の一部書き換えられていました。また、プロンプトの形状も"■"ではなく"_"でした。
高解像度(HGR)で280x192ドット6色(白、黒、青、赤、紫、緑)のグラフィックが使えます。テキストベースのPCが多かった時代に、カラーでグラフィックスが表示出来るマシンは斬新でした。このグラフィックは少々"クセが強い"為、「にじみ」と呼ばれるApple][特有の絵柄となりました。基本的に、画素1pixelに対して、VRAMの1bitが割り当てられていたので、本来ならON/OFFの2値しか表現出来ないはずですが、7pixel分を1byte単位で扱い最上位bitで色グループが変わる事と、偶数、奇数の桁位置で出せる色が決まっていて隣のpixel(bit)のON/OFFに影響されて発色が異なる為、ドット単位で意図した色が出せるとは限らない仕様でした。メモリが貴重な時代の苦肉の策だったのかもしれません。
テキストは40桁X24行表示でアルファベットは大文字のみで小文字は出せませんでしたが、反転や点滅はできました。別途、80桁カードを刺せば80桁で小文字も表示出来たようです(これは当時、持ってませんでした)。テキストタイプのアドベンチャーゲームなど、大文字だけの40桁表示は読みづらかった思い出があります。
互換機を購入して最初に見たApple][エミュレータにすっかりハマっていた頃に、//cの内蔵DISKからデータを吸い上げる為に書いたコードです。//cは友人が所有していたものを借りました。6502はファミコンでも採用されたのでご存知の方も多いでしょう。今となっては何の役にも立ちませんけど、、、
;
; DISKTERM Ver1.00
; written by H.Kanemoto.,Nov.20.1993.
;
; usage: ]BLOAD DISKTERM
; ]CALL -151
; *800G
;
; description:
; 9600bps/8bit/パリティーナシ/STOPビット=1 の状態で無手順、テキスト転送を
; 行います。送り出す データ は、DISK][ の セクター0 から順に読み出
; された バイナリーデータ を 16進数字文字列に変換しています。][c の
; シリアル 専用なので、他の シリアルカードについては改良が必要でしょう。
; (コメント は、おかしな英文ですがご勘弁を!)
;
; Appendix: Apple IIc serial port connector signals (DIN 5pin)
;
; 3 1 DTR Data Terminal Ready output
; 2 4 2 TD Transmit Data output
; 1 5 3 GND Power and signal common
; 4 RD Read Data input
; 5 DSR Data Set Ready input
;
DATA .equ $C0A8 ; 6551 data reg
STATUS .equ $C0A9 ; 6551 status reg
COMMAND .equ $C0AA ; 6551 command reg
CONTROL .equ $C0AB ; 6551 control reg
;
; INITIALIZE ROUTINE:
;
; setup serial controller 6551.
;
;
0800- 8D A9 C0 start: STA $C0A9 ; reset 6551
0803- A9 0B LDA #$0B ; non-parity
0805- 8D AA C0 STA $C0AA ; set command reg
0808- A9 1E LDA #$1E ; stop1/8bit/9600bps
080A- 8D AB C0 STA $C0AB ; set control reg
;
; MAIN ROUTINE:
;
; read whole diskett sector by sector.
;
;
080D- AD 05 0C main: LDA $0C05 ; sector No.
0810- C9 10 CMP #$10 ; end-of-sector?
0812- D0 10 BNE read
0814- A9 00 LDA #$00 ; reset sector No.
0816- 8D 05 0C STA $0C05
0819- EE 04 0C INC $0C04 ; ++ track No.
081C- AD 04 0C LDA $0C04 ; get track No.
081F- C9 23 CMP #$23 ; end-of-track?
0821- D0 01 BNE read
0823- 60 RTS ; exit program
0824- A9 0C read: LDA #$0C ; IOB addr-H
0826- A0 00 LDY #$00 ; IOB addr-L
0828- 20 D9 03 JSR $03D9 ; _rwst DOS routine
082B- EE 05 0C INC $0C05 ; ++ sector No.
082E- 20 40 08 JSR print ; dump/trans sector
0831- 4C 0D 08 JMP main
0834- 00 BRK
: : ; NOT USED
083F- 00 BRK
;
; PRINT ROUTINE:
;
; dump a page of data (one sector,256 bytes)
;
;
0840- A9 00 print: LDA #$00 ; init local vars
0842- 8D 28 0C STA $0C28 ; width(0-15)
0845- 8D 29 0C STA $0C29 ; column(0-15)
0848- 8D 2A 0C STA $0C2A ; index(0-255)
084B- AD 28 0C prloop: LDA $0C28 ; get width
084E- C9 10 CMP #$10 ; end-of-line?
0850- D0 13 BNE prexec
0852- A9 00 LDA #$00 ; reset width
0854- 8D 28 0C STA $0C28
0857- 20 80 08 JSR kaigyo ; send "\n" code
085A- EE 29 0C INC $0C29 ; ++ column
085D- AD 29 0C LDA $0C29 ; get column
0860- C9 10 CMP #$10 ; end-of-page?
0862- D0 01 BNE prexec
0864- 60 RTS ; exit print
0865- AC 2A 0C prexec: LDY $0C2A ; get index
0868- B9 00 20 LDA $2000,Y ; get a byte from buff
086B- 20 90 08 JSR trans ; send via comm
086E- EE 28 0C INC $0C28 ; ++ width
0871- EE 2A 0C INC $0C2A ; ++ index
0874- 4C 4B 08 JMP prloop
0877- 00 BRK
: : ; NOT USED
087F- 00 BRK
;
; CR/LF ROUTINE:
;
; send "\n" ascii codes via comm
;
;
0880- A9 40 kaigyo: LDA #$40 ; "\n" str addr-L
0882- 85 4A STA $4A ; unused ZERO-PAGE
0884- A9 0C LDA #$0C ; "\n" str addr-H
0886- 85 4B STA $4B ; by system.
0888- 20 C0 08 JSR sends ; send line via comm
088B- 60 RTS
088C- 00 BRK
: : ; NOT USED
088F- 00 BRK
;
; TRANSLATE ROUTINE:
;
; convert a byte of data according to format.
;
;
0890- 48 trans: PHA ; arg in A reg
0891- 4A LSR ; use left 4 bit
0892- 4A LSR
0893- 4A LSR
0894- 4A LSR
0895- 20 B0 80 JSR hex2asc ; convert hex to ascii
0898- 8D 48 0C STA $0C48 ; put it in send buff
089B- 68 PLA ; use right 4 bits
089C- 20 B0 08 JSR hex2asc
089F- 8D 49 0C STA $0C49
08A2- A9 48 LDA #$48 ; str addr-L
08A4- 85 4A STA $4A
08A6- A9 0C LDA #$0C ; str addr-H
08A8- 85 4B STA $4B
08AA- 20 C0 08 JSR sends ; send line via comm
08AD- 60 RTS
08AE- 00 BRK
08AF- 00 BRK
;
; HEX2ASCII ROUTINE:
;
; convert a number in renge of 0 to 15 to numeric string.
;
;
08B0- 29 0F hex2asc:AND #$0F ; mask lo 4 bits
08B2- A8 TAY
08B3- B9 30 0C LDA $0C30,Y ; get ascii from table
08B6- 60 RTS
08B7- 00 BRK
: : ; NOT USED
08BF- 00 BRK
;
; SEND LINE ROUTINE:
;
; send a line of strings to comm.
;
;
08C0- A0 00 sends: LDY #$00 ; reset ptr
08C2- B1 4A sdloop: LDA ($4A),Y ; get a char
08C4- F0 07 BEQ sdexit ; NULL char?
08C6- 20 D0 08 JSR send ; send a char via comm
08C9- C8 INY ; ++ ptr
08CA- 4C C2 08 JMP sdloop
08CD- 60 sdexit: RTS
08CE- 00 BRK
08CF- 00 BRK
;
; SEND CHAR ROUTINE:
;
; send a char to comm port with checking a status.
;
;
08D0- 48 send: PHA ; send data in A reg
08D1- AD A9 C0 wait: LDA $C0A9 ; get 6551 status
08D4- 29 10 AND #$10 ; check trans ready bit
08D6- C9 10 CMP #$10
08D8- D0 F7 BNE wait
08DA- 68 PLA
08DB- 8D A8 C0 STA $C0A8 ; out to 6551 data reg
08DE- 60 RTS
08DF- 00 BRK
: : ; NOT USED
0BFF- 00 BRK
;
; ZERO PAGE:
;
; $004A-$004B: pointer to string,this area not used in system
;
; DATA AREA:
;
; $0C00-$0C10: IOB
; $0C20-$0C23: RD
; $0C28-$0C2A: variables for print routine
; $0C30-$0C3F: ascii code table for hex2asc routine
; $0C40-$0C42: CR/LF strings
; $0C48-$0C4B: convrted number strings
;
; BUFFER:
; $2000-$20FF: buffer for readed sector datas
;
0C00- 01 60 01 00 00 00 20 0C ; IOB
0C08- 00 20 00 00 01 00 00 60
0C10- 01 00 00 00 00 00 00 00
0C18- 00 00 00 00 00 00 00 00
0C20- 00 01 EF D8 00 00 00 00 ; DR
0C28- 00 00 00 00 00 00 00 00
0C30- 30 31 32 33 34 35 36 37 ; "0" "1" "2" "3" "4" "5" "6" "7"
0C38- 38 39 41 42 43 44 45 46 ; "8" "9" "A" "B" "C" "D" "E" "F"
0C40- 0D 0A 00 00 00 00 00 00 ; CR LF NULL
0C48- 00 00 20 00 00 00 00 00
.end start
たまにはアセンブラも楽しいもんですよw