From 905f81d15cc52c3c1403c55db3db85668b87bddc Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 16 Oct 2021 20:23:00 +0900 Subject: [PATCH] ways to modify font rom but untested --- assets/FontROM7x14.png | Bin 3892 -> 3694 bytes assets/hp2640.png | Bin 7595 -> 6848 bytes assets/lcd2.png | Bin 2939 -> 2745 bytes assets/wpfont.png | Bin 6979 -> 6188 bytes .../tsvm/peripheral/GraphicsAdapter.kt | 89 +++++++++++++++++- terranmon.txt | 9 +- 6 files changed, 92 insertions(+), 6 deletions(-) diff --git a/assets/FontROM7x14.png b/assets/FontROM7x14.png index eac15dc0135aab5e79e4c1b87ef8748e4aa45e26..d50fcfd6cd3bf4d5fd3de488ec42aad871ec6614 100644 GIT binary patch delta 3693 zcmV-z4wCV-9_}2FB!6&eLqkw$V`BgSD3NuMy-UMT6va2!bMrxcCqFwMdEgHH8*wU%0tH z&U@$basv3%Iy3B^1YnpB&!&>nYJN@XeMbm`R6$J1%(fOXnSV68uAfKvM1P2jS>4Zd zT>S;rW`M7cc$Qh*A)Y5rZ#kCWJ>p?jk_*Hq#4%16B)%28;_;i{qQ_r?c`myM_{B`A z*v3j5vl2ImCyAqmUSZAqh%X7N=E^elQK~W6$RdR#Bq*q06FMBkshgBpXJ4Y>TSA#U zjNTTi;N&QxM1S5GsTG>4QrAdV>CsUYx&P18)@G)?>ER?0e0AN=aiDh}sMlQg_tbUk zXF%WuxHenY8M!Jwq!0hqyUv)(}0f)U?2|+-29tr-HK&dQa=5TdMWxHqi-*!>IS;mx`^-^Ci%OKA5=YJ%1=>81% zyrmALY<~xF%=sNFsjc^CsNXF@dLdFK&A9u=?$2p|BaE1zrT#AomsBtJo;H|whIwW$ zC#3TPpeBWxffSRf7%>lsRzFv6Z4dW7>Njb&d1o&r9P{sY_4@nwZ`pDqMq-4qIP@zi%w|~yvpRG2wuE?OHmMACbbBFJ0f-0k! zD%EM}8#P-b^=e($sQ-Is-d)gse;cTpL72!%C8f(NEW)b3MFqlR7u>D?``8VwF%dsd zW0GdsQSVA+D_w_qW}$8IEIHKQ$3Q~g4yAbwp7GOk1bKy`vCyWbtuxnS3{)Brl>qr` z8Gncj66c#({3okFCDr9M1iWRZ(}nmu7C6ZR3rX&Y73GoI;&r4?v7G-1bXiSj3s{^n zI24xXQM;BcDP%yUT>~$JGPcVuWH9D|=3uT&f5_4i6ms)A-O{d!m8qUx6A1_znvs&N za-$EcyxV9TRE8RhC62rXEPq!CM`a%@#+wDfnfLXq#uJAve=KG@GSJ9O znI+Hix0eYBxNP0HMFHzO^Jkpc`ku-_4PfRZ!s0ei13*clv@33rP7f1y`(4W%`d*3{J0)bs^JAt&0=d4CN+ z_Tq?WJCS}oksp`kVUI&!!36KodC8i60xBfYRmB8qmU2QdKXdoZsIn&yc($vhGBEp; z@qDUTyEsy@!yy3&=rXZekjk9*8RxS)=h9hA?>S5a3_!lQ8o{ByXWEU(ZlHvb&gzqT zHhQSm3n*w?Oj*i3m?qGq0)X%cvL42dQPs;Q2^} zh?C1X<4C=h_mC57T)E_$oM;J3P~-=>Nrc=$LVP+ax`IMhTK~L#M|?d`n|~3Xc1SZS zJcfj;1NBXwO`y8l^&GB%)$DR0csZP?RGAerxAs(J|59(U?fqNrA@* zl!F4rUZC4^vDBjKD~>TnwE*(|Slv+X?b}M&%d%v6pft|-$Q+a5mAVRWI2yV!Tk0dK zoMK{h{U%kY*BywM?$$x`lz(Zv{8>!eVTC^VF8{I4^={0w1N}7h>}zUjYHE5UxpyNx z!4b5(>=Cy``F!C6rYPP<>H<)Y7?wVw6-D1qsd$bY`^$WC1sLSp)MOdL`1 zyw?+_si~={#ya<|ZBJPbGj6_mV&Y_4#Ht&y)7$n@e+<78@HivpG1-vp;DK#NZ9ofVczR{Z%OON9KMY1#MA-p`|9U)+x19 zQ+HaqS0l_>x_{B}y#F>lQnT7gKH3W0tX>DQ=BygnCm}t%ZH5jrk|1cu-i@%_Hz3dJ zGw*SC4z%wfQT`&TI+6u@o{4jts_sU-lCpiolXqf1Z(>^JI{JiA%uP*AO-;Q9p0f5@ z!#_WMO?}Jx8cW9Q>i)MQ|8Q%2L~j|*fUJhDOS=kLw||U&%U9e^+QGa#XfUXO*E&B} zirgnyeU#mcV(f^nPmQ;f1X_)iW*s2zw;gMprcp8?=|>?lYJ8}J#9SNh?_ZUYFAZw7 zim8|p_r7J^1JrILl_&l{C2bd=tA)%&n72aUt=F^v#Xw|NAw!K(%+S7PSwA^Li4rDs zw`G?RBY%DqVbI&}M|e-j?eqi3Pg9zOtEs^XB>}%le*q ziP5_FXVzOGEZG-3)xJ}A4kA*4pbUtlMH!LN7VSN4ursaKaNdNbH3k)%M;^(< zsNSlws1se0Xe2tG)+OP3WAvi0g7eS?yUT1rYrSQt5%W5f-xphi`nE;D=8jTM}SM$&sZ?Aku+h>w#h~o@+JTwco9EdVq=ljzLBS z=YOYKei7fx;y+qWw^OIE5dj%UC#9p_)|u%otH{oh#dr%eCOPd9x@KLjNeHrAp1A|? zcB2Uqg8MiPO$BNp`+GB3A1~@o18Qe*&tAxj)P7boj-M^_ctuRm1<%#TCcI@xCTi^-ynj|Na)V16^9C0lj9#@0Olj#ZVNp7oE+H_d=GL`XjVlGn6iOqr%mWysCjaVi zAdO53GxJoFpNsaZm1VbONRsW%tAOr%S@KmxaxPSdVj?# zqijWbos6IcnQNgo7E~LqRfF|JC)qlKwGd?1OrM->AX(*?HH%3@Xf%WF@n)>dv+TQ4 z0zxtOE5c18S+6y%K&@*M^Sn_ktVy2TcK{Hxo~rZ2;}4OUXhD@KV7<>b&c4iaITrs@ zQmM^AhtIZqt?y$fO&GdB{mY>yS$}?#c6GY~Rgn&Dc_TJ@>O{VES&$Rz-)v)}$w!w4 zfpJWf7~iy*fjt9z2KEfxL}P}9=Ko7fqynB+#d4`|AtHh7tl&m<-v>40JTuUWHA>G& zgNs_MvzpKJ2fgQUq&-8V@Aqey&p@Xe_1%1ydpjm>wdCyCmSFWRD{UCG-hea40BA)vU^ApD_D)D1()#9OgN3}3!0rq8+YoR-}f#n^Sr6I zsfbCO8m7L1B=E2%&40?6N!&Z!cya-esK7)>doD!Uq}jFA5;H`fmu4Osy}mMC`aPAw zv5x%8pa@>W!+K#x5_ByBR)$Ky-po8ojjs|K?weeia_>yOq;-SR_nrZuu1ir?l{ML8 zmJrNFfi{qwF@dy2Q{|p@@JN&Yj(;8LS-J0d+9E9-uUDbF z0`f^HP-a`kPgClQLztSO4X#MTtwGMEB#4<17IjE@RYXOrkD1+$k7av@`>56!%X?_u z7Ho6XdWSNkB3bi@bW++`sFHY#6TBMfiMBmr1LI-lvd1~Z49i+PwQbKaw|$oLR`(DlhpKO?Vx9kTj_gcsM3g!m)#F@ zXs{g?oJA#{uDVvXRlFkSH5|NUr(23o0}DPo8`KPpGqAUl9!~!OR#q}J@-VM}00000 LNkvXXu0mjfC%+Ob delta 3880 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 diff --git a/assets/hp2640.png b/assets/hp2640.png index 6816d2d28cb6dff5fb6b57d0c5b98139d2a16856..99590c34458360e628981a332a87e9d7d50322f0 100644 GIT binary patch literal 6848 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 literal 7595 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 delta 2916 zcmV-q3!C)075f&DB!6*fLqkw$V`BgSD3NuMyGz4R6vn?k#8;(*4x%C%syMVz6vR>M z(4|PJ6|A}>w@E7`X}C#|;wrc}6dXhsUxWXFu7azAASi-}i~oSHMM^xkDYQs?!p-^d z-SZvpJs0q&bY|GWIAE9#&mR z2>crP{a?AKO8fP)E(|k(om87h)m^==|FB`efInWZ*XPUmK0p8er;m@1usrj9wPm&8 zm7_5-V~Xlqb3^l0*Jz&C5iQL7=iT5uf%ETPov6%f)B2m$pS8f&IxqzH2y*`YV0PF1 z$M1%%4y?aX7Jn2G7`5RoLZ-fYs=YquQ*d5~cOM6{8@yvzSRStK zv5j}#_m4%K_vwgEfOV3>6Y&1AIy`qU55QZLXm_Fd>V`lIJrm}>k-E+BB=f_4w1bDvn z-(m51BoDH%(vl}$c@=SFSj}YwUE|PdP=TU!b?6OuA=tqxODZl`Q9%{Xs^hWH zP6SQa4Z(1M_rDLcV{?HIw1gUJ&+AtmkGJU7Vlu+qQm(8r?;925f>1+5gt;st zy4tT--+v=Ig1(*}G($>6U~j$$f^ZBDXA~tw7-VB%`_0rx`iD10Px(~l`(w>MPdze9 z3p(=FjzEftvY?C=vtm`f>iZ@Dy8w5d%&*h~A_!>l&kP*wfQVVReAn-5e8;YiW@Qc$ zkC6!st3mBttp~ivn<9X6AK)om3IvU01^RmrL4V!ll#H&1JXq$zFV{E);9%!CkX6sw? zIoO?DIr63g0&dXG#Ok)~L<^7X`%75j>$wluih4`}C_)lx#>{SF>oeDXk>5_I{}L-7 zP=6h3JOf!J6)R>0D;3n>VS1!DMCK4{UJAQWEtew-LeMYd3WlyZ$;0g1J09MA&o&-}5$a;fC+NY=FD5hjqZ?Jxk+-evW#5i%W zvePOb83CoR8D%kdBan=i&zt}S{z4R_qJNzTbs*&{<5|qMqg+*H7nZH__yyhU8|qF( zyif71XYPKPwpbV)L0%TlMzTj8&&V{Ct_PPGDO(LCP#E-$g&R9PNaFVJ3n(#Zvld6zLB?EW)rz4lSdD@SP!V+`ikbP!r#vF zik`uO5lINI)B~=t{V04nVlPa*8uGY~=6vj$=*oT+cktDq0LdHK6wxJwvrv$=x_Z`1 zwVe)ls(M`<5!^&P6T#M<9%q?=Y=3owteVr2rGDh{w@Z^$k9<{e>?XosI%5K`RTh-3 z-{CFCAh~R&7Nu?&sQrBFh4-OSvw8%TelpRM%D=Oo((_n4k<+;Q4y&337{lIG0{AZi zc*;~3o-%*Kw9h*8dU+YVwj*B8-0h-qqVb%|2a92&WEHH+j@rvARo;n-e1C&jk7^Yd zSpVIBUj?2SnBc z!qoTJlIq#lsl+|^0XO-MT^-#$W;fD5yzD2xh5)}w!(|ar<(l-H0LahX3aqw*uIKtz zRxGbQi(juU&t&TAB=EUU>VHOzO>7k18m&MUs*x`1t<4JTSw}*#)8BePM}R}ug-ixU zq6-km24e3w!i{8|VQD1w}R?FAr$cPJ}=_EY6~@OutOt(|<}kCa3s{PwH^C z&G_$k*l>3D+ui;T0;tlx8uP`LXFSxhm7{T1Q_`%|1)@zeyb2ypS5pIYm3usw9gh;nP~9{V zu^v6(26}*M<7VCisDI+|4&2?D-!ytZA)Q5DJpl}wxQjl~b>*peJgDq;Fe&Plpy(7wkxBTRG(DI$c)HsGPDIn$1h?@t87G`fMeew$bY6nV6wV&8Rs57;5X<2 z)pE}pBJz?@ar!R%O=rKye6-ZpLZk9IgefX#EugFII~BW_1z^057NQ{bW{UCGrxV!) zb|N;Kv$FVX3QOkUP9(Pm5-N(lo83vQUrsf*r>c>5zEj2oHM)L5JIu4p+g;V&8ew;f zP;A~e*1et4x_^&ZBVEZq8T`GoZ;z17D;vz5tai+_l_=h+ir=fYmlZ}gRSRBaEPV8U zJLmzC{RiRq4xGNq$c5Tb+h6%^+TrEYx7f&e(YrGi{;S{c5-XwCj4VRz5|%9guLe$J zH<(&~Sehw10kfo6^?+!Css`GXSWk@zjZF1uUVo*pUw?f9)P-iWU?xqDdP3REjx1r= zby$7^RKj$%qv{u3HYT`H|PP~846jmZ3c}YXnK1Bcvp{Ab1UQCtw2g^oXDSNwM${E3{V$3lTIcg7}LHI z5~S)M)%VA;a$-b{?nq=>ee1VV&_6Kr(F30E7Jo7z!_PbFSJ9OxUzAJt44R6Pn|uAH z>$m8D7yb*%_$@Z#kjgGWpSr`^&n?leu`@nLBU{N-& zk`T^JV5NPZv9GMS&05JmVO=j@P*)Dn9SEq~vbthC?hWIk2ka&8{QU>N{t7=jkN({N O00009qc#l-T3Oavz93I|17NQ4# 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 literal 6979 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 U)rtAx-wYZ^QA43d&OH2o0Ez{I^8f$< diff --git a/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt b/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt index 3048c06..47ed126 100644 --- a/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt +++ b/src/net/torvald/tsvm/peripheral/GraphicsAdapter.kt @@ -2,6 +2,7 @@ package net.torvald.tsvm.peripheral import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.* +import com.badlogic.gdx.graphics.g2d.Gdx2DPixmap import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.glutils.FrameBuffer @@ -66,7 +67,7 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super val channel = it % 4 rgba.shr((3 - channel) * 8).and(255) / 255f } - protected val chrrom0 = Texture("./assets/"+config.chrRomPath) + protected val chrrom0 = Texture(Pixmap(Gdx2DPixmap(Gdx.files.internal("./assets/"+config.chrRomPath).read(), Gdx2DPixmap.GDX2D_FORMAT_ALPHA))) protected val faketex: Texture internal val textArea = UnsafeHelper.allocate(7682) @@ -84,6 +85,8 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super private var chrHeight = 14f var framebufferScrollX = 0 var framebufferScrollY = 0 + private var fontRomMappingMode = 0 // 0: low, 1: high + private var mappedFontRom = ByteArray(1920) override var ttyFore: Int = TTY_FORE_DEFAULT // cannot be Byte override var ttyBack: Int = TTY_BACK_DEFAULT // cannot be Byte @@ -187,6 +190,7 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super 250897L -> framebufferScrollX.ushr(8).toByte() 250898L -> framebufferScrollY.toByte() 250899L -> framebufferScrollY.ushr(8).toByte() + in 252030 until 252030+1920 -> mappedFontRom[adi- 252030] in 250880 until 250880+1024 -> unusedArea[addr - 250880] in 253950 until 261632 -> textArea[addr - 253950] in 261632 until 262144 -> peekPalette(adi - 261632) @@ -214,6 +218,7 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super 250897L -> framebufferScrollX = framebufferScrollX.and(0xFFFF00FF.toInt()).or(bi shl 8) 250898L -> framebufferScrollY = framebufferScrollY.and(0xFFFFFF00.toInt()).or(bi) 250899L -> framebufferScrollY = framebufferScrollY.and(0xFFFF00FF.toInt()).or(bi shl 8) + in 252030 until 252030+1920 -> mappedFontRom[adi- 252030] = byte in 250880 until 250880+1024 -> unusedArea[addr - 250880] = byte in 253950 until 261632 -> textArea[addr - 253950] = byte in 261632 until 262144 -> pokePalette(adi - 261632, byte) @@ -280,9 +285,83 @@ open class GraphicsAdapter(val vm: VM, val config: AdapterConfig, val sgr: Super framebuffer.setColor(0f,0f,0f,arg1 / 255f) framebuffer.fill() } + 3 -> { + for (it in 0 until 1024) { + val rgba = DEFAULT_PALETTE[it / 4] + val channel = it % 4 + rgba.shr((3 - channel) * 8).and(255) / 255f + } + framebuffer.setColor(0f,0f,0f,arg1 / 255f) + framebuffer.fill() + } + 4, 5 -> readFontRom(opcode - 4) + 6, 7 -> writeFontRom(opcode - 6) } } + /** + * @param mode 0-Low, 1-High + */ + open fun readFontRom(mode: Int) { + // max char size: 8*15 + fontRomMappingMode = mode + val cw = config.width / config.textCols + val ch = config.height / config.textRows + if (cw > 8 || ch > 15) throw UnsupportedOperationException() + + chrrom0.textureData.prepare() + val pixmap = chrrom0.textureData.consumePixmap() + val scanline = ByteArray(cw) + val dataOffset = mode * chrrom0.width * chrrom0.height / 2 + + for (char in 0 until 128) { + for (line in 0 until ch) { + pixmap.pixels.position((char / 16) * (cw * 16 * ch) + (char % 16) * cw + dataOffset) + pixmap.pixels.get(scanline) + var word = 0 + for (bm in 0 until scanline.size) { + val pixel = (scanline[bm] < 0).toInt() + word = word or (pixel shl (scanline.size - 1 - bm)) + } + mappedFontRom[char * ch + line] + } + } + + pixmap.dispose() + } + + /** + * @param mode 0-Low, 1-High + */ + open fun writeFontRom(mode: Int) { + // max char size: 8*15 + fontRomMappingMode = mode + val cw = config.width / config.textCols + val ch = config.height / config.textRows + + if (cw > 8 || ch > 15) throw UnsupportedOperationException() + + chrrom0.textureData.prepare() + val pixmap = chrrom0.textureData.consumePixmap() + val scanline = ByteArray(cw) + val dataOffset = mode * chrrom0.width * chrrom0.height / 2 + + for (char in 0 until 128) { + for (line in 0 until ch) { + val word = mappedFontRom[char * ch + line] + for (bm in 0 until scanline.size) { + val pixel = 255 * (word and (1 shl (scanline.size - 1 - bm)).toByte() < 0).toInt() + scanline[bm] = pixel.toByte() + } + pixmap.pixels.position((char / 16) * (cw * 16 * ch) + (char % 16) * cw + dataOffset) + pixmap.pixels.put(scanline) + } + } + + pixmap.dispose() + } + + override fun resetTtyStatus() { ttyFore = TTY_FORE_DEFAULT ttyBack = TTY_BACK_DEFAULT @@ -1033,7 +1112,7 @@ void main() { vec4 tileCol = texture2D(tilesAtlas, finalUVCoordForTile); // apply colour. I'm expecting FONT ROM IMAGE to be greyscale - gl_FragColor = linmix(backColFromMap, foreColFromMap, tileCol.r); + gl_FragColor = linmix(backColFromMap, foreColFromMap, tileCol.a); } """.trimIndent() @@ -1161,7 +1240,7 @@ void main() { vec4 tileCol = texture2D(tilesAtlas, finalUVCoordForTile); // apply colour. I'm expecting FONT ROM IMAGE to be greyscale - gl_FragColor = linmix(backColFromMap, foreColFromMap, tileCol.r); + gl_FragColor = linmix(backColFromMap, foreColFromMap, tileCol.a); } """.trimIndent() @@ -1247,7 +1326,7 @@ void main() { vec4 palCol = vec4(1.0); // apply colour - if (tileCol.r > 0) { + if (tileCol.a > 0) { palCol = foreColFromMap; } else { @@ -1344,7 +1423,7 @@ void main() { vec4 palCol = vec4(1.0); // apply colour - if (tileCol.r > 0) { + if (tileCol.a > 0) { palCol = foreColFromMap; } else { diff --git a/terranmon.txt b/terranmon.txt index e8d3c85..7711fa9 100644 --- a/terranmon.txt +++ b/terranmon.txt @@ -156,6 +156,11 @@ From the start of the memory space: command (writing to this memory address changes the status) 1: reset palette to default 2: fill framebuffer with given colour (arg1) + 3: do '1' then do '2' + 4: copy Low Font ROM (char 0–127) to mapping area + 5: copy Low Font ROM (char 128–255) to mapping area + 6: write contents of the font ROM mapping area to the Low Font ROM + 7: write contents of the font ROM mapping area to the High Font ROM 12 bytes argument for "command" (arg1: Byte, arg2: Byte) write to this address FIRST and then write to "command" to execute the command @@ -165,8 +170,10 @@ From the start of the memory space: framebuffer scroll Y 896 bytes horizontal scroll offset for scanlines -2154 bytes +234 bytes unused +1920 + mapped to font ROM 2 bytes Cursor position in: (y*80 + x)