mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-09 14:44:05 +09:00
i18n driver for tvdos
This commit is contained in:
@@ -11,8 +11,8 @@ let errorlevel = 0;
|
||||
|
||||
const termWidth = con.getmaxyx()[1];
|
||||
const termHeight = con.getmaxyx()[0];
|
||||
const welcome_text = (termWidth > 40) ? "TSVM Disk Operating System, version " + _TVDOS.VERSION
|
||||
: "TSVM Disk Operating System " + _TVDOS.VERSION;
|
||||
const welcome_text = (termWidth > 40) ? "TSVM 한글 DOS, 버전 " + _TVDOS.VERSION
|
||||
: "TSVM 한글 DOS " + _TVDOS.VERSION;
|
||||
const greetLeftPad = (termWidth - welcome_text.length - 6) >> 1;
|
||||
const greetRightPad = termWidth - greetLeftPad - welcome_text.length - 6;
|
||||
|
||||
@@ -255,7 +255,7 @@ shell.coreutils = {
|
||||
// check if path is valid
|
||||
var dirOpenedStatus = filesystem.open(CURRENT_DRIVE, path.string, 'R');
|
||||
var isDir = filesystem.isDirectory(CURRENT_DRIVE); // open a dir; if path is nonexistent, file won't actually be opened
|
||||
if (!isDir) { printerrln("CHDIR failed for '"+path.string+"'"); return dirOpenedStatus; } // if file is not opened, IO error code will be returned
|
||||
if (!isDir) { printerrln("디렉토리 '"+path.string+"'가 없습니다."); return dirOpenedStatus; } // if file is not opened, IO error code will be returned
|
||||
|
||||
shell_pwd = path.pwd;
|
||||
},
|
||||
@@ -270,7 +270,7 @@ shell.coreutils = {
|
||||
// check if path is valid
|
||||
var dirOpenedStatus = filesystem.open(CURRENT_DRIVE, path.string, 'W');
|
||||
var mkdird = filesystem.mkDir(CURRENT_DRIVE);
|
||||
if (!mkdird) { printerrln("MKDIR failed for '"+path.string+"'"); return dirOpenedStatus; }
|
||||
if (!mkdird) { printerrln("디렉토리 생성 실패: '"+path.string+"'"); return dirOpenedStatus; }
|
||||
},
|
||||
cls: function(args) {
|
||||
con.clear();
|
||||
@@ -313,7 +313,7 @@ shell.coreutils = {
|
||||
// if value is undefined, show what envvar[key] has
|
||||
if (value === undefined) {
|
||||
if (_TVDOS.variables[key] === undefined)
|
||||
println("Environment variable '"+key+"' not found");
|
||||
println("환경변수 '"+key+"'이(가) 없습니다.");
|
||||
else
|
||||
println(_TVDOS.variables[key])
|
||||
}
|
||||
@@ -331,7 +331,7 @@ shell.coreutils = {
|
||||
|
||||
// check if path is valid
|
||||
var pathOpenedStatus = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
|
||||
if (pathOpenedStatus != 0) { printerrln("File not found"); return pathOpenedStatus; }
|
||||
if (pathOpenedStatus != 0) { printerrln("파일이 없습니다"); return pathOpenedStatus; }
|
||||
|
||||
var port = filesystem._toPorts(CURRENT_DRIVE)[0]
|
||||
com.sendMessage(port, "LIST");
|
||||
@@ -341,7 +341,7 @@ shell.coreutils = {
|
||||
var pathstr = (args[1] !== undefined) ? args[1] : shell.getPwdString();
|
||||
|
||||
var pathOpenedStatus = filesystem.open(CURRENT_DRIVE, pathstr, 'R');
|
||||
if (pathOpenedStatus != 0) { printerrln("File not found"); return pathOpenedStatus; }
|
||||
if (pathOpenedStatus != 0) { printerrln("파일이 없습니다"); return pathOpenedStatus; }
|
||||
let contents = filesystem.readAll(CURRENT_DRIVE);
|
||||
// TODO just print out what's there
|
||||
print(contents);
|
||||
@@ -393,7 +393,7 @@ shell.execute = function(line) {
|
||||
}
|
||||
|
||||
if (!fileExists) {
|
||||
printerrln('Bad command or filename: "'+cmd+'"');
|
||||
printerrln('명령어 또는 파일 이름이 틀립니다: "'+cmd+'"');
|
||||
return 127;
|
||||
}
|
||||
else {
|
||||
@@ -480,7 +480,7 @@ if (exec_args[1] !== undefined) {
|
||||
goInteractive = true;
|
||||
}
|
||||
else {
|
||||
printerrln("Invalid switch: "+exec_args[1]);
|
||||
printerrln("잘못된 스위치: "+exec_args[1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
assets/disk0/tvdos/i18n/hang_hi.chr
Normal file
BIN
assets/disk0/tvdos/i18n/hang_hi.chr
Normal file
Binary file not shown.
BIN
assets/disk0/tvdos/i18n/hang_lo.chr
Normal file
BIN
assets/disk0/tvdos/i18n/hang_lo.chr
Normal file
Binary file not shown.
225
assets/disk0/tvdos/i18n/korean.js
Normal file
225
assets/disk0/tvdos/i18n/korean.js
Normal file
@@ -0,0 +1,225 @@
|
||||
let status = 0
|
||||
let workarea = sys.malloc(1920)
|
||||
|
||||
// install LOCHRROM
|
||||
status = filesystem.open("A", "/tvdos/i18n/hang_lo.chr", "R")
|
||||
if (status != 0) {
|
||||
printerrln("hang_lo.chr not found")
|
||||
sys.free(workarea)
|
||||
return status
|
||||
}
|
||||
dma.comToRam(filesystem._toPorts("A")[0], 0, workarea, 1920)
|
||||
for (let i = 0; i < 1920; i++) sys.poke(-1300607 - i, sys.peek(workarea + i))
|
||||
sys.poke(-1299460, 18)
|
||||
|
||||
|
||||
// install HICHRROM
|
||||
status = filesystem.open("A", "/tvdos/i18n/hang_hi.chr", "R")
|
||||
if (status != 0) {
|
||||
printerrln("hang_hi.chr not found")
|
||||
sys.free(workarea)
|
||||
sys.poke(-1299460, 20) // clean up the crap
|
||||
return status
|
||||
}
|
||||
dma.comToRam(filesystem._toPorts("A")[0], 0, workarea, 1920)
|
||||
for (let i = 0; i < 1920; i++) sys.poke(-1300607 - i, sys.peek(workarea + i))
|
||||
sys.poke(-1299460, 19)
|
||||
|
||||
|
||||
|
||||
sys.free(workarea)
|
||||
|
||||
graphics.setHalfrowMode(true)
|
||||
/*
|
||||
* A character is defined as one of:
|
||||
* 1. [I,x] (Initial only)
|
||||
* 2.1. [I,x,I,x] (Double Initial)
|
||||
* 2.2. [Ip,x,P,x] (Initial and Peak)
|
||||
* 3.1. [Ip,F,P,x] (Initial, Peak and one Final)
|
||||
* 3.2. [Ip,F1,P,F2] (Initial, Peak and complex Final)
|
||||
* 4.1. [I,x,Ip,x,P,x] (Double Initial and Peak)
|
||||
* 4.2. [I,x,Ip,F,P,x] (Double Initial, Peak and Final)
|
||||
* 4.3. [I,x,Ip,F1,P,F2] (Double Initial, Peak and complex Final)
|
||||
*
|
||||
* Index 0,2,4 is always top and 1,3,5 is always bottom row.
|
||||
*
|
||||
* ## Character Cell Numbering
|
||||
* +--+--+--+
|
||||
* |c0|c2|c4|
|
||||
* |c1|c3|c5|
|
||||
* +--+--+--+
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
let charmap = {
|
||||
i:{ // Cell Indices: [c0,c2]
|
||||
// c0,c2:[ㄱ,ㄴ,ㄷ,ㄹ,...]
|
||||
0:[0],
|
||||
1:[0,0],
|
||||
2:[1],
|
||||
3:[2],
|
||||
4:[2,2],
|
||||
5:[3],
|
||||
6:[4],
|
||||
7:[5],
|
||||
8:[5,5],
|
||||
9:[6],
|
||||
10:[6,6],
|
||||
11:[7],
|
||||
12:[8],
|
||||
13:[8,8],
|
||||
14:[9],
|
||||
15:[10],
|
||||
16:[11],
|
||||
17:[12],
|
||||
18:[13]
|
||||
},p:{ // Cell Indices: [c2,c4], where c2 will be work as an multiplier
|
||||
// c2:[null,ㅗ,ㅛ,ㅜ,ㅠ,ㅡ]
|
||||
// c4:[0xC6,ㅏ,ㅐ,ㅑ,ㅒ,ㅓ,ㅔ,ㅕ,ㅖ,ㅘ,ㅙ,ㅚㅢㅟ,ㅝ,ㅞ,ㅣ]
|
||||
0:[0,1],
|
||||
1:[0,2],
|
||||
2:[0,3],
|
||||
3:[0,4],
|
||||
4:[0,5],
|
||||
5:[0,6],
|
||||
6:[0,7],
|
||||
7:[0,8],
|
||||
8:[1,0],
|
||||
9:[1,9],
|
||||
10:[1,10],
|
||||
11:[1,11],
|
||||
12:[2,0],
|
||||
13:[3,0],
|
||||
14:[3,12],
|
||||
15:[3,13],
|
||||
16:[3,11],
|
||||
17:[4,0],
|
||||
18:[5,0],
|
||||
19:[5,11],
|
||||
20:[0,14]
|
||||
},f:{ // Cell Indices: [c3,c5]
|
||||
// c3,c5:[null,ㄱ,ㄴ,ㄷ,...]
|
||||
0:[0,0],
|
||||
1:[1,0],
|
||||
2:[1,1],
|
||||
3:[1,7],
|
||||
4:[2,0],
|
||||
5:[2,9],
|
||||
6:[2,14],
|
||||
7:[3,0],
|
||||
8:[4,0],
|
||||
9:[4,1],
|
||||
10:[4,5],
|
||||
11:[4,6],
|
||||
12:[4,7],
|
||||
13:[4,12],
|
||||
14:[4,13],
|
||||
15:[4,14],
|
||||
16:[5,0],
|
||||
17:[6,0],
|
||||
18:[6,7],
|
||||
19:[7,0],
|
||||
20:[7,7],
|
||||
21:[8,0],
|
||||
22:[9,0],
|
||||
23:[10,0],
|
||||
24:[11,0],
|
||||
25:[12,0],
|
||||
26:[13,0],
|
||||
27:[14,0]
|
||||
}}
|
||||
|
||||
let enc = {
|
||||
i:[
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,
|
||||
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,
|
||||
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,
|
||||
0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,
|
||||
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,
|
||||
0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd
|
||||
],p:[
|
||||
0xc6,0x8e,0x8f,0xae,0xaf,0xce,0xcf,0xee,0xef,0xb0,0xb1,0xb2,0xb5,0xb6,0xfe
|
||||
],f:[
|
||||
0x20,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0x13,0x14,0x15,0x16,0x17
|
||||
]
|
||||
}
|
||||
|
||||
function toLineChar(i,p,f) {
|
||||
let out = []
|
||||
let ibuf = charmap.i[i]
|
||||
let pbuf = charmap.p[p]
|
||||
let fbuf = charmap.f[f]
|
||||
let dbl = 2*(ibuf.length == 2) // 0 or 2
|
||||
/* 0 | 0 */out[0] = ibuf[0]
|
||||
/* x | 2 */out[2] = ibuf[1]
|
||||
/* 2 | 4 */out[2+dbl] = pbuf[1]
|
||||
/* | */out[dbl] += pbuf[0]*14
|
||||
/* 1 | 3 */out[1+dbl] = fbuf[0]
|
||||
/* 3 | 5 */out[3+dbl] = fbuf[1]
|
||||
|
||||
if (out.length > 4) {
|
||||
out[0] = enc.i[out[0]]
|
||||
out[1] = 0x20
|
||||
out[2] = enc.i[out[2]]
|
||||
out[3] = enc.f[out[3]]
|
||||
out[4] = enc.p[out[4]]
|
||||
out[5] = enc.f[out[5]]
|
||||
}
|
||||
else {
|
||||
out[0] = enc.i[out[0]]
|
||||
out[1] = enc.f[out[1]]
|
||||
out[2] = enc.p[out[2]]
|
||||
out[3] = enc.f[out[3]]
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
let cursReturn = () => {
|
||||
let c = graphics.getCursorYX()
|
||||
con.move(c[0]-1,c[1]+1)
|
||||
}
|
||||
|
||||
let printHangul = (char) => {
|
||||
char.forEach((v,i)=>{
|
||||
con.addch(v)
|
||||
if (i % 2 == 0)
|
||||
con.curs_down()
|
||||
else
|
||||
cursReturn()
|
||||
})
|
||||
}
|
||||
|
||||
let printComma = (char) => {
|
||||
con.addch(char)
|
||||
con.curs_down()
|
||||
con.addch(127)
|
||||
cursReturn()
|
||||
}
|
||||
|
||||
// load unicode module to the TVDOS
|
||||
if (unicode.uniprint) {
|
||||
unicode.uniprint.unshift([
|
||||
c => 0x2C == c || 0x3B == c || (0xAC00 <= c && c <= 0xD7A3),
|
||||
c => {
|
||||
if (0x2C == c || 0x3B == c) {
|
||||
printComma(c)
|
||||
}
|
||||
else {
|
||||
let i = ((c - 0xAC00) / 588)|0
|
||||
let p = ((c - 0xAC00) / 28 % 21)|0
|
||||
let f = (c - 0xAC00) % 28
|
||||
printHangul(toLineChar(i,p,f))
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
println("조합한글 커널모듈이 로드되었습니다.")
|
||||
return 0
|
||||
}
|
||||
else {
|
||||
println("Failed to load Assembly Hangul kernel module: incompatible DOS version")
|
||||
return 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user