懐かしのMS-DOSプログラミング ver.2
■ このスレッドは過去ログ倉庫に格納されています
mov dx,offset msg
mov ah,9
int 21h
mov ax,4c00h
int 21h
msg db '懐かしのDOS時代のプログラミングについて語ろうぜ ver.2',0dh,0ah,'$'
前スレ
懐かしのMS-DOSプログラミング
http://toro.2ch.net/test/read.cgi/tech/1271821343/ LSI C-86試食版 Ver.3.30c
http://www.lsi-j.co.jp/freesoft/
ぜひとも手にしておきたいDOS用国産フリーCコンパイラ echo テスト > tes.com
tes
# 「テ」一文字だけでいいんだけどね DOSのエミュレータを使えば、いろんな環境でDOSとまったく同じように使えます。 >>2
スモールモデルしか対応していないのが残念なんだが int 21hとか直接書いてたのっていつ頃なんだ? >1000 デフォルトの名無しさん [sage] 2014/05/18(日) 23:04:42.60 ID:rUyw0YMJ Be:
> Windows 8.1でもdosソフトウェアは、うごきますか?
DOXBOX おすすめ あれ
打ちまちがえた
x DOXBOX
o DOSBOX >>6
でもfarが使えるから大きなデータは外へ出しちゃえばかなりのことができる。
ご丁寧にfar文字列処理関数も入ってる。 Turbo Cがタダで使えるのに LSIC86 試食版を今更使う理由が分からん >>13
CP/M 対応も考慮したプログラム作法が理解できんとは CP/M86なんて使ってたやついたのかね。
call 5なんて、知識レベルでの互換性の意味しかないだろ…。 四半世紀前に、バイト先の別働隊が
コンカレントCP/MとかC-DOSの案件
やってたのを思い出した。 >>14
コードセグメントが near ポインタのみの64KBというのは、ちと狭すぎやしないか‥ >>15
フリーの MS-DOS 用 C コンパイラってあるの? >>20
Turbo C
GCC(要djgpp)
他にもあるやろ >>17
そゆこと
DOSでcall 5を使うのは「俺はお前らと違ってCP/Mから知ってんだぞドヤァ」の意味にしかならない >>16
そこで自分から“CP/M”を口にしてしまうようでは、煽り師失格だな >>21
turbo c ってフリーなの?
でもオープンソースじゃないよね
gcc(djgpp) は i386 以上を要求するしね >>24
オープンソースでi386未満がターゲットのコンパイラが欲しかったの?
条件後出し乙。
その条件だと心当たり無いわ。
役立たずで申し訳ない。 パソ通全盛期の80年代末、フリーウェアはほとんどがTurbo Cで書かれてたね。
俺はQuick Cへ行ったけど。 そうか?
アセンブラも多かった気がするよ。
そんな俺は、TurboPascalをasm文だけ使って構造化アセンブラとして駆使してた。 TurboPascalってasm文をテンポラリファイルに書き出して子プロセスでtasm呼び出してたし、
asm文しか使わんなら素直にtasm直に使ったほうが便利だろ。 いや、tasmいらんよ、アセンブラを内蔵してる。
tasmとか呼び出すのはとろくさいC系だろ。 OpenWatcomのことを思い出してあげてください・・・ >>24, >>25
Open Watcom C/C++ はどう?
DOSエクステンダ不要なバイナリーも
作れたハズ Turbo Cはコンパイルも速いし、吐き出したコードもMS-Cより2〜3割速かった Open Watcomはインラインアセンブラ周りでいろいろ罠があって勧めにくい QuickCって学習用と謳っておきながら
ラージどころかヒュージモデルのライブラリまで入ってたね。
実際にQCでそんな巨大なアプリ書く奴いたのだろうか・・・ そらゲームとかの素材置きまくったらあっという間ですわ ヒュージポインタはいまいち信頼出来ないと思っていた‥‥
セグメント-オフセット処理は自分でなんとかしないといけないと思うよ‥‥
というか、やっぱり 64KB 以上のオブジェクトをそのまま使おうと思っちゃいけない、自分で完全管理するしかないと
というわけで、LSI-C にラージモデル(だけでいいのでそ)のサポートがほしかった
>>35
自分で探すべきなんだろうけれども、たとえばどんなところが罠なんですか? >>38
Open WatcomのBugzillaでinlineとかをキーワードで検索するといろいろと
何年も放置された未修正のバグの山が出てくる LSIC-80 今でも使ってますよ。XPまではDOS窓で動いたのに、7になったら
動かなくなって、仮想マシンとか調べたら対象のOSをインストールしなければ
いけないのね。困ってたらnetでmsdos.exe見つけ、それ経由で使えてラッキー。
8085+82XXの基板がまだあって、去年は\3万の仕事を2件やりました(w
DOSでCW、エコロジーとか使ってた頃が懐かしい(w CWはemm386.exeと相性悪くロックしたりした。 REDもそうかな? CWとほとんど同じ使い勝手だったのは覚えてるけど。 ああ俺もだな。
メルコの4MB-EMSボード使っていたからというのもあるけど 細かな指定ができるのはメルウェアが一番だったな。
ディスクキャッシュは糞だったけど。 ダメルコのディスクキャッシュソフトで何枚FDが死んだ事か…。 MSDN垢持ってるひとは今でもMS-DOS6.22が手に入る。6.2/Vも。
16bitコンパイラはあったかな。
Visual C++1.52cのリンカーってDOSのEXE吐けたっけ? 吐けるよ。win3.1用exeもdllもvbxも
quick win用exeもスタティックlibも
P-codeもcomも。 RAMDiskで768KBぐらい使って、そこに中間ファイルのパス張っておくと
コンパイルが速いってのをやったなあ。5インチ縦置き20MBのディスクの頃。 TurboPASCALはコンパイル速かったなあ
ディスクキャッシュ上でコンパイルして実行。フロッピーへは遅延書き込み パスカルはワンパスでコンパイルできる言語仕様だからな。
ヘッダも分離してないし、当時のマシンスペックには最適の高級言語だった。
関係ないが、アップルのSwiftがちょっとパスカル臭がしてうれしい。 Turbo Cも1パスで高速、安価、吐き出したコードもMS-Cより高速と
いいところずくめだった。日曜プログラマは一斉にTCへ流れた感じがある。
特にMSAが98用に移植した1.5が大ヒットしたね。 プリプロセッサがあったり前方参照が可能なCが1パスでコンパイルできるわけない ところが、BorlandのCはプリプロセッサも含めて1パス
#if中でsizeofあたりも使えたんだぜ
最近clang化したせいでできなくなった 理解不足で速いと言いたいだけだろとも思ったけど、clang化でできなくなったというからには何か構造的なレベルでこ違いを感じてるのかなあ
つか#if内でsizeofって逆にパス増やしてない?それともプリプロセッサ内でも自然に扱えるように独自実装積み上げてたのかな Cはどれも似たり寄ったりだけど、ターボアセンブラは至宝! QuickCのコンパイル速度だけは感動した気がする >>57
> #if中でsizeofあたりも使えたんだぜ
#if sizeof(int)==4
typedef int int32;
#elif sizeof(long)==4
typedef long int32;
#endif
とかやれても limits.h あるし意味ないよなあ、移植性失うし。どういう便利な使い方あんの? >>56
pascal にも前方参照あるし、前方参照は call 命令だけ吐いといてあとからオペランド埋めればいいだけだよ >>64
> pascal にも前方参照あるし、
本質的にできないからforwardなんてのが後からUCSDに追加されたりしたんだけど。 >>65
それがどうかしたのか?
前方参照できるのは事実だろ。 ん?
横レス
本質的にできない、ってワンパスでは、ってことではないのかな。実際ワンパスで実現する方法はないよね
いや、まああえて言えばシンボル保存した上での実行時の遅延評価までやるのなら可能だろうけど。
cでそんなことやるにはobj-cみたいにランタイム用意しなきゃ無理だろ 機械語レベルの前方参照なら>>64の言う通り、何も難しい事は無いし
ソースレベルの前方参照は、C言語はそもそも不可能だろ、普通forward宣言が必要なのを前方参照とは言わんしな
(C++でクラス内ではまだソースコードに出現してないメンバ変数名を使えたりするようなのがそれ)
>>59 ひとつのコンパイラがプリプロセスから構文解析、意味解析をトークンごとに一気に行ってるからできるわけでパスは増えてないよ
ていうかこれが1パスでないなら1パスって何なんだ >>68
> ソースレベルの前方参照は、C言語はそもそも不可能だろ、普通forward宣言が必要なのを前方参照とは言わんしな
ごめん、意味がわからない
> (C++でクラス内ではまだソースコードに出現してないメンバ変数名を使えたりするようなのがそれ)
そんなことできないし 話にならんな
class t {
int f(){
return m; //この時点でmを参照できる
}
int m;
};
こういう風にまだ出てきてない宣言を使えるのが前方参照で、これは1パスでは無理
CやPascalみたいにプロトタイプやforward宣言が必須なものは、その情報だけで呼び出し側の生成には充分だからこそ必須になってる訳で1パスで可能 バブル絶頂の80年代末、パソ通が黎明期から普及期へと移り変わった頃
Vz + TCCは俺の青春って人は多いだろうね >>71
ちょっとおそい90年代前半だが、それでも Vz + lsic が青春でした‥ EZ→TunedEZ→NITemacsだったかな。
VZは仕事で使ってたか。 VZを常駐させるようになって、いままで多数使用していたフリーソフトを整理できたからな。 各自がシステムのフロッピーとデータ用フロッピー持って、共同パソコンを一々
立ち上げてはエディット・コンパイルとかやってたな。システムは左側。
HDD内蔵のパソコンが出た時は、フロッピースロットが1つしかない!って慌てたわ。 フロッピースロットが1つでも何とかなってたような記憶が
なんかフロッピー入れ替えてた覚えがある MS5550は3FDDでシステム&プログラム&データ おれが大学当時、大学の授業のために5インチフロッピーが必要ってのがあった。
生協で買ったよ。1枚700円ぐらいしてた。 >>80
書込み防止したまま書込みをすると警告と再試行、中止、無視の
指示要求が出る
その状態でフロッピーを入れ換えて再試行をするとDOSは入れ替え前の
状態から書き込むのでフロッピーの中身が大変なことになる >>85
PC-9801で最初にHDDを内蔵したやつでは、普段の使い方で同様に
「さっきまでのディスクのディレクトリを上書き」が発生するという酷いバグが 受信ringバッファから読みだすルーチン: LSIC80、石は8085=8080コード
char* _asm_u(char*); /* 左辺値にするための宣言*/
#define ring(ptr,ring) *(_asm_u("\n\tMVI\tH, HIGH " #ring "_\n" \
"\tLDA\t" #ptr "_\n\tMOV\tL,A\n\tINR\tA\n\tSTA\t" #ptr "_\n"))
char ch1read(void) { return ring(c1r_rpt,r1ring);
受信ringバッファに書込む割込み処理の、正常受信時の処理:
ring(c1r_wpt,r1ring) = ACHDR;<---I/Oreg. B000h番地
rptとwptはbyte、ringは[256]にして自然ラップアラウンド、添え字計算時の
アドレス演算がワード演算されないように最適化させてます。 ptrを1バイトにするために
MVI H,HIGH ring
LDA ptr
MOV L,A
INR A
STA ptr
MOV A,M
として11バイト50クロックにするより、素直にptrに2バイト使って
LHLD ptr
MOV A,M
INR L
SHLD ptr
として8バイト44クロックのほうがメリットあると思う。
ptrを1バイトにする以前にringバッファに256バイトもいるのかまず検討すべき。 わを!4行でできるのか(*o*) ptrの頭はゼロのまま・・・あ!違うか初期化で
先頭+00にしとくのですね。今度使ってみます。ありがとう!!
ringは32と64で周回遅れが出たことがありますが、
主な理由は++した後マスク演算が要らないからです。
4CHあって、各受信256送信512、実装8KBの半分近くがringです(w
再構成するフレームがせいぜい80byte5種類位なのでこれでも余裕です。
最初に書いたときは受信バイト数を持って、書き込みで++読み出しで--、
片方は割込みだからタスク側で DI/EI してとかややこしい事書いてました。
自分では簡潔になったと思ってましたが、診て貰ってよかったです(m_ _m) >>88 の部分は確かに上の最適化可能ですが、システム全体の性能はどっこい
なことが判りました。メインループで「そのCHに受信データがあるか?」の判定
のところで、rptrとwptrを並べて配置してあることを利用して、
LHLD rptr ;wptrとrptr両方
MOV A,H
XRA L
CNZ そのCHの受信フレーム再構成処理 と最適化してます。
こっちでメモリアクセスが1行増えるから、全体の性能はどっこいなのでした。
80C85のデータシート見たら、機械語の説明表でステート数とサイクル数
という欄があるのですが、これらはどう見ればいいのですか? ここで答え書いてもらうより
ステートとかで検索してみれば 一般用語から類推すると、ステート数=CPUクロック数 だと思えますが、
サイクル数ってのがステートより少し小さい数字で出ていて、こちらが何の事か
想像できないんです。どちらの数字に1/原CLKを掛けたものが実行時間とか。 メーカーさんのサイトでも覗いてみれば
もしくは電凸?答えられる人いるかな
うろ覚えだからな、ヘタにかけないし 当時はステート数で実行時間を計算してたよ
DMAがどうとかウェイトサイクルがどうとか、そんな話だった気がする 何クロックだかで1ステートとか1サイクルとか、そういう定義があった。
きちんとした資料なら定義がちゃんと書いてあるだろうし、書いてないならいまさら
確認するのは無理だからあきらめろ。 沖電気の80C85のpdfの中探してみましたが、定義なしで使っていました。
4ステートの命令が1サイクル、7ステートが2サイクル、10ステートが3サイクル
なので、3で割った商で近似できそう。メモリアクセスの量みたいですね。
reg,reg 命令が一番少なくて、LDA/STAのようにメモリアクセス1回だと2サイクル
メモリアクセス2回だと3サイクル、call/return はpush/pop & jump だから
もっとサイクル数が多い。 8085は条件分岐が成立しないと 命令の3バイト目の読み込みをスキップするから2サイクルになるぞ ■ このスレッドは過去ログ倉庫に格納されています