From 5dee7d555c06dbbece84b8489fc3db9446ef0096 Mon Sep 17 00:00:00 2001 From: Roman Boykov Date: Thu, 19 Feb 2026 19:13:56 +0300 Subject: [PATCH] Monitor r7 with crc32: 93bd95db disasm completed. --- CPM_v2.2_r8_099942fc/.gitignore | 10 - CPM_v2.2_r8_2e4a7b71/.gitignore | 10 - CPM_v2.2_r8_bc0695e4/.gitignore | 10 - CPM_v2.2_r8_ddd05ed7/.gitignore | 10 - MON_Turbo/.gitignore | 10 - MON_Turbo/turbo_mon.asm | 1 + MON_r6_291f2b76/.vscode/extensions.json | 9 + MON_r6_291f2b76/.vscode/tasks.json | 65 + MON_r6_291f2b76/BIN/MON_r6_291f2b76.BIN | Bin 0 -> 8192 bytes MON_r6_291f2b76/README.md | 15 + MON_r6_291f2b76/bios_entries.inc | 41 + MON_r6_291f2b76/equates.inc | 149 + MON_r6_291f2b76/font-6x7.inc | 165 + MON_r6_291f2b76/io.inc | 132 + MON_r6_291f2b76/m_vars.inc | 112 + MON_r6_291f2b76/mon_entries.inc | 35 + MON_r6_291f2b76/monitor.asm | 4933 ++++++++++++++++++++ MON_r6_291f2b76/ram.inc | 49 + MON_r7_58d6d2a8/.gitignore | 10 - MON_r8_3edeb015/.gitignore | 10 - MON_r8_9c6c6546/.vscode/extensions.json | 9 + MON_r8_9c6c6546/.vscode/tasks.json | 34 + MON_r8_9c6c6546/BIN/MON_r8_9c6c6546.BIN | Bin 0 -> 8192 bytes MON_r8_9c6c6546/README.md | 19 + MON_r8_9c6c6546/bios_entries.inc | 41 + MON_r8_9c6c6546/equates.inc | 149 + MON_r8_9c6c6546/font-6x7.inc | 165 + MON_r8_9c6c6546/io.inc | 132 + MON_r8_9c6c6546/m_vars.inc | 101 + MON_r8_9c6c6546/mon_only.map | 449 ++ MON_r8_9c6c6546/monitor.asm | 5596 ++++++++++++++++++++++ MON_r8_9c6c6546/ram.inc | 49 + MON_r8_bedc54ad/.vscode/extensions.json | 9 + MON_r8_bedc54ad/.vscode/tasks.json | 34 + MON_r8_bedc54ad/BIN/MON_r8_bedc54ad.BIN | Bin 0 -> 8192 bytes MON_r8_bedc54ad/README.md | 16 + MON_r8_bedc54ad/bios_entries.inc | 41 + MON_r8_bedc54ad/equates.inc | 149 + MON_r8_bedc54ad/font-6x7.inc | 165 + MON_r8_bedc54ad/io.inc | 132 + MON_r8_bedc54ad/m_vars.inc | 101 + MON_r8_bedc54ad/mon_only.map | 449 ++ MON_r8_bedc54ad/monitor.asm | 5597 +++++++++++++++++++++++ MON_r8_bedc54ad/ram.inc | 49 + MON_r8_c4eec374/.gitignore | 10 - 45 files changed, 19192 insertions(+), 80 deletions(-) delete mode 100644 CPM_v2.2_r8_099942fc/.gitignore delete mode 100644 CPM_v2.2_r8_2e4a7b71/.gitignore delete mode 100644 CPM_v2.2_r8_bc0695e4/.gitignore delete mode 100644 CPM_v2.2_r8_ddd05ed7/.gitignore delete mode 100644 MON_Turbo/.gitignore create mode 100644 MON_r6_291f2b76/.vscode/extensions.json create mode 100644 MON_r6_291f2b76/.vscode/tasks.json create mode 100644 MON_r6_291f2b76/BIN/MON_r6_291f2b76.BIN create mode 100644 MON_r6_291f2b76/README.md create mode 100644 MON_r6_291f2b76/bios_entries.inc create mode 100644 MON_r6_291f2b76/equates.inc create mode 100644 MON_r6_291f2b76/font-6x7.inc create mode 100644 MON_r6_291f2b76/io.inc create mode 100644 MON_r6_291f2b76/m_vars.inc create mode 100644 MON_r6_291f2b76/mon_entries.inc create mode 100644 MON_r6_291f2b76/monitor.asm create mode 100644 MON_r6_291f2b76/ram.inc delete mode 100644 MON_r7_58d6d2a8/.gitignore delete mode 100644 MON_r8_3edeb015/.gitignore create mode 100644 MON_r8_9c6c6546/.vscode/extensions.json create mode 100644 MON_r8_9c6c6546/.vscode/tasks.json create mode 100644 MON_r8_9c6c6546/BIN/MON_r8_9c6c6546.BIN create mode 100644 MON_r8_9c6c6546/README.md create mode 100644 MON_r8_9c6c6546/bios_entries.inc create mode 100644 MON_r8_9c6c6546/equates.inc create mode 100644 MON_r8_9c6c6546/font-6x7.inc create mode 100644 MON_r8_9c6c6546/io.inc create mode 100644 MON_r8_9c6c6546/m_vars.inc create mode 100644 MON_r8_9c6c6546/mon_only.map create mode 100644 MON_r8_9c6c6546/monitor.asm create mode 100644 MON_r8_9c6c6546/ram.inc create mode 100644 MON_r8_bedc54ad/.vscode/extensions.json create mode 100644 MON_r8_bedc54ad/.vscode/tasks.json create mode 100644 MON_r8_bedc54ad/BIN/MON_r8_bedc54ad.BIN create mode 100644 MON_r8_bedc54ad/README.md create mode 100644 MON_r8_bedc54ad/bios_entries.inc create mode 100644 MON_r8_bedc54ad/equates.inc create mode 100644 MON_r8_bedc54ad/font-6x7.inc create mode 100644 MON_r8_bedc54ad/io.inc create mode 100644 MON_r8_bedc54ad/m_vars.inc create mode 100644 MON_r8_bedc54ad/mon_only.map create mode 100644 MON_r8_bedc54ad/monitor.asm create mode 100644 MON_r8_bedc54ad/ram.inc delete mode 100644 MON_r8_c4eec374/.gitignore diff --git a/CPM_v2.2_r8_099942fc/.gitignore b/CPM_v2.2_r8_099942fc/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/CPM_v2.2_r8_099942fc/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld - diff --git a/CPM_v2.2_r8_2e4a7b71/.gitignore b/CPM_v2.2_r8_2e4a7b71/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/CPM_v2.2_r8_2e4a7b71/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld - diff --git a/CPM_v2.2_r8_bc0695e4/.gitignore b/CPM_v2.2_r8_bc0695e4/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/CPM_v2.2_r8_bc0695e4/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld - diff --git a/CPM_v2.2_r8_ddd05ed7/.gitignore b/CPM_v2.2_r8_ddd05ed7/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/CPM_v2.2_r8_ddd05ed7/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld - diff --git a/MON_Turbo/.gitignore b/MON_Turbo/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/MON_Turbo/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld - diff --git a/MON_Turbo/turbo_mon.asm b/MON_Turbo/turbo_mon.asm index dce4612..fb3c343 100644 --- a/MON_Turbo/turbo_mon.asm +++ b/MON_Turbo/turbo_mon.asm @@ -139,6 +139,7 @@ i_fill_video: ; Beep LD C, ASCII_BELL CALL m_con_out + ; check bios exists LD A, (BIOS.boot_f) CP JP_OPCODE JP Z, BIOS.boot_f diff --git a/MON_r6_291f2b76/.vscode/extensions.json b/MON_r6_291f2b76/.vscode/extensions.json new file mode 100644 index 0000000..1fdc4e8 --- /dev/null +++ b/MON_r6_291f2b76/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "maziac.asm-code-lens", + "maziac.dezog", + "maziac.hex-hover-converter", + "maziac.z80-instruction-set", + "maziac.sna-fileviewer" + ] +} diff --git a/MON_r6_291f2b76/.vscode/tasks.json b/MON_r6_291f2b76/.vscode/tasks.json new file mode 100644 index 0000000..ed01311 --- /dev/null +++ b/MON_r6_291f2b76/.vscode/tasks.json @@ -0,0 +1,65 @@ +{ + "version": "2.0.0", + "tasks": [ + + { + "label": "make MONITOR (sjasmplus)", + "type": "shell", + "command": "sjasmplus", + "args": [ + "--sld=monitor.sld", + "--sym=monitor.labels", + "--raw=monitor.obj", + "--fullpath", + "monitor.asm" + ], + "problemMatcher": { + "owner": "sjasmplus", + "fileLocation": "autoDetect", + "pattern": { + "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "severity": 3, + "message": 4 + } + }, + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Optimize MONITOR (MDL)", + "type": "shell", + "command": "/opt/java21/bin/java -jar ~/Soft/MDL/mdl.jar monitor.asm -cpu z80 -so -dialect sjasmplus", + "group": "build", + "problemMatcher": { + "applyTo": "allDocuments", + "fileLocation": [ + "autoDetect", + "${workspaceFolder}" + ], + "pattern": [ + { + "regexp": "^(\\w+): (.+) in (.+)#([0-9]+): (.+)$", + "file": 3, + "line": 4, + "severity": 1, + "message": 5, + "code": 2 + } + ] + }, + "presentation": { + "echo": false, + "focus": false, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true, + "revealProblems": "onProblem" + } + } + + ] +} \ No newline at end of file diff --git a/MON_r6_291f2b76/BIN/MON_r6_291f2b76.BIN b/MON_r6_291f2b76/BIN/MON_r6_291f2b76.BIN new file mode 100644 index 0000000000000000000000000000000000000000..c6b7a69bbf4e7ada03354e7889a4ae014b6a345f GIT binary patch literal 8192 zcmeG>3wImUnRjH#dc=C!mV@oYBSm&d;()=>Wa~}F%2R}pC`|$mJ%AkwYYv5afi99C zk)0*kw1+*Agp@;}%Z8quZfNN$Jc@D}He=7My`DKt7F)+zS0+s)*<(5Kn@W}hne2B* zvSTRw1NI!ontQ+d-S7QNGv**IBI>Md_v)y4f8fITfvKQyrr{~yH zbL^P}yFbCUr`S(Y?7B4TOn*Uj1lT}?dM&VpY7c}cBG8qKY^b)aXVc%?KVg1wjY5Gg zN*!RTleDjToUWdstEcIz>M5Gass4hdwg8VZ5Ux(qHl$qf7ux0^RwQWZQs5n`0`3@{H&JGi^q-wSvLkSQ*~j5Zd%iNG~+T`)r61o}S|t;8PhmWNt^X;uzMbhzLjG z(0YZR$Ay;o;2}}X{BwwXDU=8NU45bF0NMXLoA1Zg&$xz;f?s9tUMIH17r^JE5b41?Re~k zK|7llwt2&V3_cz3`7X0NT=zw)UZIpP}uS(XJt4&!35Xex~$cwlKZ_QLj{! zej;*NEgFx(<+S7RPv!ABdwzkQc_acNy`r(c(!Wm8TZEo3wOx!97e8iyCAmE$ju6C=^#*~piX$EQAz;J+&o z&K#yo8VgFAV1*TAfCSC;VM!pGlf`$MZ{8)84=*p8mLt1#SU4A!N_#Pi(G3?}1Aw!= zHY_v@+mvWUn$ATAB)mQR>;HUicuktN1I9pneXR6I-I_|eABQ?h=%R# z!Qn10ZhHey0P_QY+Xc7nEsU7KBwXna6(ywy5Q3(p)KyY5LwEEPG!1mOifU&oNs=OY ztjE#VED}c=@k8ga^74o9qehhu47ZSVtz8uPOgYX4Lh?jT^(@Ub)%)riR~N4?Zj~JAJ4b3}X+MAG$VPt6NUPKU z2y-VqXmd4yUDtsVfdt#n*eEo=uKLU4fguPev3^WhCcd$pFier?F&XM)EwIkt|}#79X}% zHdU<#5jj8!)&dM{FpzEdTd@#l#&&RQ#5O_Oy*-3j>y}nkChb0VB@Ua035wpHB~rTI zJ?iG{-pfEB)$*^4?n;ij-CgOuyrlovA~lQWdNf&P_IYv51Px_zw5d%}I@1AB%yG8) zNk8dYnd>{EX9TgMqi1uYLCs;=#{OZ^%>j8+&ysqBMt)B@Ryy{VxXTMwOhQ}>!I}{b zOMs$BQ=jW7azMgVjCmCBd862VQ0}knwPWMJE-8m+M&k<>Kq(s3Gm?V;uc(}TU;Z-h zv3#6?Ju>sxov-Y?rfWc|=8jY}++{JeLTA0TZV~!D!LGBob9gYt!(GuY+s0GlU*}O!>YX;g;Ik}0r!n;{5krK zQUux?QOW_jGnMEVo8QKmkt5dD#T%5C&3Ka^Tp1> z{CnAX^}K(JU4nTKDf1KaZUAm#!SYfjKW4j1uOsa1ZgP^EkH@krHx9)lR|x+=Y(~=Z zXGBTE+eW3^_(oA8dB>QfdPduAhk+u44X85nhR2 z5m=$gvI058?@|nuUy6werc-A8cofvVgVjATDi!nZjRNDdqreEwg3hmxwEW2^FufQB zrbnZ|^s^{1Jre~cXtGRe5_D|MUubGw;75l74Q+vjniTD9`LMUtGpTXPyCV}*IDTuu z+s0YlxEzR1hzM*eY?H8~xNOC5Q?UET<6!rX$NhZ6xTJ)}1MBOBamvBI0N^SNu9Cq$ z7~JD7tprx7DA+Mh6*-R`>p0fo#*5ZAPRpw;OuIx)GynEDr4fy85cvCX`Hk%ZiSWk8 zOB{`12K-LXA)OTZSNO2-Y^;J$jLfD6_Dt}ScEMZv-3aW&y!Abr;JXpGotnD{{X@de zi9?swO(V_l2JbVdM{tS$WF_+WdCSD=jf`m`)(!8oDyR4ChiBceIL>}>)?EQF=5Jss zD%QrjaOsEO%OGb0zh+KuY|8FbL<(x3vyIT^2wk%MeE+i(ZcjcqzWsdAgTWZ=^1zM} z-}3K$@N$y^AkCu1wZbn7pgT23{_`QJj@_f1wg`yy?{r>ZtY2D)9ciP&f` z%Fnz!xyafIu=brv{T=K-d<%9h`|_l0wrBm)pl@<%dAU>1{BSZ9;vSgS^dF!}7C(dK z2S>jt zh|C6c15Z4ere>IS`g^JN^GRRb0ikP(A{vjoJZdLJ9B-;EZ2cqOH3itV9!2A!9z|30 z5m$fvRBhq%mJ2ZPnnd)ro|K5iG|Hy_^Ha6WM=>4y`V@S*3Km}>Jgi7Bq_$%lpI(>wjWjR&CLvM{fohWVmtn3wS|FVk^F=;_t{ z71PD5``6&63OD!S=KHvzaI*zB_e~c+!nJh-ADXT^bhutPI}PyT0H2WI2FU^rocIrxs-4rq%16yhdLbz ze>!EE%1~%j<`ig@isIXHwJL>0Ta>F*U>ZOv6iN;J;3G?cbV^dG0|C&19Jn%MqzvO> zE;0cffehwiOM%&-%*7fF1~bNzq(-SRnGKpeotD&SNWy4>QJ#V@n#~3hQz#S$0O1FB znMsq2<-t$xlnN{u3_*y5KLikFkwqgVbVU}6L8&vFNwXOQ;-A3`pMz$DT5C3&wQ74X#mH;b%eb$Ap^Hs)rm_Oiqb~rJFv2#NOhsT=8H~&%VYm(A4WeNHA%uBMX;wnY;L;#0I+q}12W1qN zYXr+I2x&1TmI7AGosp2cG801j0?>p|8E7+R6x@ao5Ed8V4*Y`-`v)C%5F^V>d0;rs zJI<3*SD4WUpXy4DQl~-+i_W4!mh2zWT9#V0kZO%VTSVYi3yIfiwIpaaK&8r-kwh8f z8Ydd8*2*T$>%;X1Va6S3*Fw?}T9%)mk4L4DKx`7Edci-Ob{LhJ%L?-mQft-NKRKRY zH8wTl14IJU;qc_BfCwRikULxs1z1=f4i*j|)TCNt&;SV@fYn+pq!K(*E#RI- zo2^gMjBB0*@34P)I=D#4om`*TJ@5}m@U>7c*e|ovBKw!EPwXA|w@{y%O2%%%a*{i_ zzRU9QV!-8^T@Q=u6DkC2gBzEyOoT1N^aU160j#P#SfVfu7YU*Z0!2d7o)ba6}qm=v3m?(I)kT(4O)$%je2+m-FLTr0_}-_Jzym{EROF z#J)sUBH;bZ7l|dFKQfxR<_pjWr{)S|(L#c=Rm};H&T;U)UN{Hr%jRsg7$KC;b#b;G z7|hAQ`!L+ab=m4lJoZE@}0iniRhZOhJm5AL#}ecOKU z;I`dcwpr1R%}%s=@3u`lk=NhbjpJ_bVjrCw8E6rSgd%~QzE-l1LS(%s&{g8XZ>{I- z1+B-JwmA&L5#(P};)&fr-kdK}{^l0t0Fltj$KtS;Zw@qg0uAs4gyT&UGceauRp+Nv z%;+4I6A0tYeuiK%^ssb@|nZz0m}C*dqIGry5+CS6jT=>$gvOR8U$xY5W8mq)bvJ3R?&ph8%a=J2T3BdRl_T$74fo91$T?Ao*tO$i6m!Bt-hW4HzJ3y8ri z;$V7E_*Ht414Dw(q`|I^-fjY=h2t{JA5CKmUr19{_La1rIht0%?SlYUh`Y%^MM4v( z;A+04MdH)$R10`V%HEZOoMH(v7t(Bh8l$Tgqxt^yddd-R4Xl{qngiCMa-%n3w+DyP z!i_XWurq159k4_8;FOF5X;&r0uljPxDs>n-_?2Hu4nq#^Oa>+H;N1+J!L+`a)9b8T p_wIOTn{~%N>uwi*0BqX&uoeD$wBzP?*LM;4E&|_0;QwO;{ul82J$e8D literal 0 HcmV?d00001 diff --git a/MON_r6_291f2b76/README.md b/MON_r6_291f2b76/README.md new file mode 100644 index 0000000..8ef52d9 --- /dev/null +++ b/MON_r6_291f2b76/README.md @@ -0,0 +1,15 @@ +# Ocean-240.2 ROM Monitor release 6 + +**CRC32 checksum**: 291f2b76 + +Source codes of Turbo Monitor r6 for Ocean-240.2 with Floppy controller. + +In Z80 mnemonics, but limited for i8080 instruction set. + +## Compile: + +Code is located in memory at address: 0xE000..0xFFFF + + sjasmplus --sld=monitor.sld --sym=monitor.labels --raw=monitor.obj --fullpath monitor.asm + +To compile sources, use [sjasmplus Z80 assembler](https://github.com/z00m128/sjasmplus). diff --git a/MON_r6_291f2b76/bios_entries.inc b/MON_r6_291f2b76/bios_entries.inc new file mode 100644 index 0000000..117a2c8 --- /dev/null +++ b/MON_r6_291f2b76/bios_entries.inc @@ -0,0 +1,41 @@ + +; ======================================================= +; Ocean-240.2 +; Definition of CPM BIOS entries to compile depended +; modules +; +; By Romych 2025-09-09 +; ====================================================== + IFNDEF _BIOS + DEFINE _BIOS + + MODULE BIOS + +boot_f EQU 0xD600 +wboot_f EQU 0xD603 +const_f EQU 0xD606 +conin_f EQU 0xD609 +conout_f EQU 0xD60C +list_f EQU 0xD60F +punch_f EQU 0xD612 +reader_f EQU 0xD615 +home_f EQU 0xD618 +seldsk_f EQU 0xD61B +settrk_f EQU 0xD61E +setsec_f EQU 0xD621 +setdma_f EQU 0xD624 +read_f EQU 0xD627 +write_f EQU 0xD62A +sectran_f EQU 0xD630 +reserved_f1 EQU 0xD633 +reserved_f2 EQU 0xD636 +tape_read_f EQU 0xD639 +tape_write_f EQU 0xD63C +tape_wait_f EQU 0xD63F + +bios_var04 EQU 0xD64B + + ENDMODULE + + + ENDIF diff --git a/MON_r6_291f2b76/equates.inc b/MON_r6_291f2b76/equates.inc new file mode 100644 index 0000000..b1b5622 --- /dev/null +++ b/MON_r6_291f2b76/equates.inc @@ -0,0 +1,149 @@ +; ====================================================== +; Ocean-240.2 +; Equates for all assembly sources +; +; By Romych 2025-09-09 +; ====================================================== + + IFNDEF _EQUATES + DEFINE _EQUATES + +ADDLIST EQU 0x08 +ASCII_BELL EQU 0x07 ; Make Beep +ASCII_BS EQU 0x08 ; Move cursor left (Back Space) +ASCII_TAB EQU 0x09 ; Move cursor right +8 pos +ASCII_LF EQU 0x0A ; Move cursor down (Line Feed) +ASCII_FF EQU 0x0C ; Move cursor to home (Form Feed) +ASCII_CR EQU 0x0D ; Move gursor to 1st pos (Cariage Return) +ASCII_CAN EQU 0x18 ; Move cursor right +ASCII_EM EQU 0x19 ; Move cursor up +ASCII_SUB EQU 0x1A ; CTRL-Z - end of text file marker +ASCII_ESC EQU 0x1B ; +ASCII_US EQU 0x1F ; Clear screen +ASCII_SP EQU 0x20 +ASCII_DEL EQU 0x7F + +; ------------------------------------------------------ +BDOS_NFUNCS EQU 41 +BELL_PIN EQU 0x08 ; DD67 Pin PC3 - "BELL" +; ------------------------------------------------------ +CCP_COMMAND_SIZE EQU 5 ; max length of CCP command +CCP_COMMAND_COUNT EQU 3 ; Count of CCP commands +CCP_COMMAND_CNT EQU 6 +CCP_COMMAND_LEN EQU 4 + +CCP_SRC_ADDR EQU 0xc000 ; Address of CCP resident part in ROM +CCP_DST_ADDR EQU 0xb200 ; Address of CCP resident part in RAM +CCP_SIZE EQU 0x809 + +CPM_VERSION EQU 0x22 ; Version of CP/M as byte nibbles '2.2' + +CTRL EQU 0x5E ; ^ +CTRL_C EQU 0x03 ; Warm boot +CTRL_H EQU 0x08 ; Backspace +CTRL_E EQU 0x05 ; Move to beginning of new line (Physical EOL) +CTRL_J EQU 0x0A ; LF - Line Feed +CTRL_M EQU 0x0D ; CR - Carriage Return +CTRL_P EQU 0x10 ; turn on/off printer +CTRL_R EQU 0x12 ; Repeat current cmd line +CTRL_S EQU 0x13 ; Temporary stop display data to console (aka DC3) +CTRL_U EQU 0x15 ; Cancel (erase) current cmd line +CTRL_X EQU 0x18 ; Cancel (erase) current cmd line + +; ------------------------------------------------------ +DBPLIST EQU 0x0F +DEF_DISK_A_SIZE EQU 0x3F +DEF_DISK_B_SIZE EQU 0x0168 +DIR_BUFF_SIZE EQU 128 +DSK_MAP EQU 0x10 +DSK_MSK EQU 0x03 +DSK_SHF EQU 0x02 +DMA_BUFF_SIZE EQU 0x80 +; ------------------------------------------------------ +ENDDIR EQU 0xFFFF +ESC_CMD_END EQU 0x1A +;EXT_NUM EQU 12 ; Extent byte offset +; ------------------------------------------------------ +FALSE EQU 0x00 +FDC_DD80RB EQU 0x21 +FDC_NOT_READY EQU 0x80 +FDC_RESTORE_L EQU 0x08 +FDC_SEEK_LV EQU 0x1C +FDC_RESTORE_UH_NV EQU 0x03 ; Restore Unload Head, No Verify, 15ms Rate +FILE_DELETED EQU 0xE5 +FWF_MASK EQU 0x80 ; File Write Flag mask + +; --------------------------------------------------- +; FCB Offsets +; --------------------------------------------------- +FCB_LEN EQU 32 ; length of FCB +FCB_SHF EQU 5 +FN_LEN EQU 12 ; Length of filename in FCB + +FCB_DR EQU 0 ; Drive. 0 for default, 1-16 for A-P +FCB_FN EQU 1 ; Fn - Filename, 7-bit ASCII. The top bits - attributes +FCB_FT EQU 9 ; Filetype, 7-bit ASCII. + ; T1' to T3' have the following + ; T1' - Read-Only + ; T2' - System (hidden) + ; T3' - Archive +FCB_EXT EQU 12 ; EX - Set this to 0 when opening a file and then leave it to + ; CP/M. You can rewind a file by setting EX, RC, S2 and CR to 0. +FCB_S1 EQU 13 ; S1 - Reserved. +FCB_S2 EQU 14 ; S2 - Reserved. Bit 7 - wile write flag, [6:0] module number (Extent hi bits) +FCB_RC EQU 15 ; RC - Set this to 0 when opening a file and then leave it to CP/M. +FCB_AL EQU 16 ; AL - Image of the second half of the directory entry, + ; containing the file's allocation (which disc blocks it owns). +FCB_CR EQU 32 ; CR - Current record within extent. It is usually best to set + ; this to 0 immediately after a file has been opened and + ; then ignore it. +FCB_RN EQU 33 ; Rn - Random access record number. A 16-bit (with R2 used for overflow) + + +; ------------------------------------------------------ +JP_OPCODE EQU 0xC3 +; ------------------------------------------------------ +IRQ_0 EQU 0x01 +IRQ_1 EQU 0x02 +IRQ_2 EQU 0x04 +;LP_IRQ EQU 0x08 +KBD_IRQ EQU 0x02 + +KBD_ACK EQU 0x10 + +KEY_ALF EQU 0x0D +KEY_FIX EQU 0x15 +; ------------------------------------------------------ +LST_REC EQU 0x7F +; ------------------------------------------------------ +MAX_EXT EQU 0x1F +MAX_MOD EQU 0x0F +;MOD_NUM EQU 0x0E +; ------------------------------------------------------ +FCB_INFO_LEN EQU 15 ; length of FCB info bytes to match +;NXT_REC EQU 0x20 +; ------------------------------------------------------ +PIC_POLL_MODE EQU 0x0A +PORT_C4 EQU 0x10 +PRINTER_ACK EQU 0x10 +PRINTER_IRQ EQU 0x08 +; ------------------------------------------------------ +;RAN_REC EQU 0x21 +;FCB_RC EQU 0x0F +RO_FILE EQU 0x09 +ROM_CHIP_SIZE EQU 8192 ; ROM Size, used to limit monitor code size + +RX_READY EQU 0x02 +; ------------------------------------------------------ +TAPE_D EQU 0x08 +TAPE_P EQU 0x04 +TIMER_IRQ EQU 0x10 +TL_HIGH EQU 0x05 +TL_LOW EQU 0x03 +TL_MID EQU 0x04 +TMR0_SQWAVE EQU 0x36 +TRUE EQU 0xFF +TX_READY EQU 0x01 +; ------------------------------------------------------ + + ENDIF \ No newline at end of file diff --git a/MON_r6_291f2b76/font-6x7.inc b/MON_r6_291f2b76/font-6x7.inc new file mode 100644 index 0000000..e9af010 --- /dev/null +++ b/MON_r6_291f2b76/font-6x7.inc @@ -0,0 +1,165 @@ +; 96 symbols 6x7, with codes 0x20..0x7f KOI-7 H0 +m_font_cp0: + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; ' ' - 0x20 + DB 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x04 ; '!' - 0x21 + DB 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 ; '"' - 0x22 + DB 0x0a, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x0a ; '#' - 0x23 + DB 0x04, 0x1e, 0x05, 0x0e, 0x14, 0x0f, 0x04 ; '$' - 0x24 + DB 0x03, 0x13, 0x08, 0x04, 0x02, 0x19, 0x18 ; '%' - 0x25 + DB 0x06, 0x09, 0x05, 0x02, 0x15, 0x09, 0x16 ; '&' - 0x26 + DB 0x06, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00 ; ' - 0x27 + DB 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08 ; '(' - 0x28 + DB 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02 ; ')' - 0x29 + DB 0x00, 0x0a, 0x04, 0x1f, 0x04, 0x0a, 0x00 ; '*' - 0x2a + DB 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00 ; '+' - 0x2b + DB 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x02 ; ',' - 0x2c + DB 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00 ; '-' - 0x2d + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 ; '.' - 0x2e + DB 0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00 ; '/' - 0x2f + DB 0x0e, 0x11, 0x19, 0x15, 0x13, 0x11, 0x0e ; '0' - 0x30 + DB 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x0e ; '1' - 0x31 + DB 0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f ; '2' - 0x32 + DB 0x1f, 0x08, 0x04, 0x08, 0x10, 0x11, 0x0e ; '3' - 0x33 + DB 0x08, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x08 ; '4' - 0x34 + DB 0x1f, 0x01, 0x0f, 0x10, 0x10, 0x11, 0x0e ; '5' - 0x35 + DB 0x0c, 0x02, 0x01, 0x0f, 0x11, 0x11, 0x0e ; '6' - 0x36 + DB 0x1f, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02 ; '7' - 0x37 + DB 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e ; '8' - 0x38 + DB 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x08, 0x06 ; '9' - 0x39 + DB 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00 ; ':' - 0x3a + DB 0x00, 0x06, 0x06, 0x00, 0x06, 0x04, 0x02 ; ';' - 0x3b + DB 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08 ; '<' - 0x3c + DB 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00 ; '=' - 0x3d + DB 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02 ; '>' - 0x3e + DB 0x0e, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04 ; '?' - 0x3f + DB 0x0e, 0x11, 0x10, 0x16, 0x15, 0x15, 0x0e ; '@' - 0x40 + DB 0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11 ; 'A' - 0x41 + DB 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f ; 'B' - 0x42 + DB 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e ; 'C' - 0x43 + DB 0x07, 0x09, 0x11, 0x11, 0x11, 0x09, 0x07 ; 'D' - 0x44 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f ; 'E' - 0x45 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01 ; 'F' - 0x46 + DB 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x1e ; 'G' - 0x47 + DB 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 ; 'H' - 0x48 + DB 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e ; 'I' - 0x49 + DB 0x1c, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06 ; 'J' - 0x4a + DB 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 ; 'K' - 0x4b + DB 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f ; 'L' - 0x4c + DB 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11 ; 'M' - 0x4d + DB 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11 ; 'N' - 0x4e + DB 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; 'O' - 0x4f + DB 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01 ; 'P' - 0x50 + DB 0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16 ; 'Q' - 0x51 + DB 0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11 ; 'R' - 0x52 + DB 0x1e, 0x01, 0x01, 0x0e, 0x10, 0x10, 0x0f ; 'S' - 0x53 + DB 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; 'T' - 0x54 + DB 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; 'U' - 0x55 + DB 0x11, 0x11, 0x11, 0x11, 0x0a, 0x0a, 0x04 ; 'V' - 0x56 + DB 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a ; 'W' - 0x57 + DB 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 ; 'X' - 0x58 + DB 0x11, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04 ; 'Y' - 0x59 + DB 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f ; 'Z' - 0x5a + DB 0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e ; '[' - 0x5b + DB 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00 ; '\' - 0x5c + DB 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e ; ']' - 0x5d + DB 0x0e, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00 ; '^' - 0x5r + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f ; '_' - 0x5f + DB 0x1c, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00 ; '`' - 0x60 + DB 0x00, 0x00, 0x0e, 0x10, 0x1e, 0x13, 0x1e ; 'a' - 0x61 + DB 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x0f ; 'b' - 0x62 + DB 0x00, 0x00, 0x0e, 0x01, 0x01, 0x01, 0x0e ; 'c' - 0x63 + DB 0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x1e ; 'd' - 0x64 + DB 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e ; 'e' - 0x65 + DB 0x18, 0x04, 0x04, 0x0e, 0x04, 0x04, 0x04 ; 'f' - 0x66 + DB 0x00, 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x0e ; 'g' - 0x67 + DB 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x11 ; 'h' - 0x68 + DB 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04 ; 'i' - 0x69 + DB 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x06 ; 'j' - 0x6a + DB 0x01, 0x01, 0x09, 0x05, 0x03, 0x05, 0x09 ; 'k' - 0x6b + DB 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08 ; 'l' - 0x6c + DB 0x00, 0x00, 0x0f, 0x15, 0x15, 0x15, 0x15 ; 'm' - 0x6d + DB 0x00, 0x00, 0x09, 0x13, 0x11, 0x11, 0x11 ; 'n' - 0x6e + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e ; 'o' - 0x6f + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x0f, 0x01 ; 'p' - 0x70 + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x1e, 0x10 ; 'q' - 0x71 + DB 0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01 ; 'r' - 0x72 + DB 0x00, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f ; 's' - 0x73 + DB 0x04, 0x04, 0x0e, 0x04, 0x04, 0x04, 0x18 ; 't' - 0x74 + DB 0x00, 0x00, 0x11, 0x11, 0x11, 0x19, 0x16 ; 'u' - 0x75 + DB 0x00, 0x00, 0x11, 0x11, 0x0a, 0x0a, 0x04 ; 'v' - 0x76 + DB 0x00, 0x00, 0x11, 0x15, 0x15, 0x15, 0x0a ; 'w' - 0x77 + DB 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11 ; 'x' - 0x78 + DB 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0c ; 'y' - 0x79 + DB 0x00, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f ; 'z' - 0x7a + DB 0x10, 0x08, 0x04, 0x02, 0x04, 0x0a, 0x14 ; '{' - 0x7b + DB 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; '|' - 0x7c + DB 0x01, 0x02, 0x04, 0x08, 0x04, 0x0a, 0x05 ; '}' - 0x7d + DB 0x00, 0x02, 0x15, 0x0a, 0x15, 0x08, 0x00 ; '~' - 0x7e + DB 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15 ; [DEL] - 0x7f + +; 64 symbols 6x7, with codes 0x40..0x7f KOI-7 H1 +m_font_cp1: + DB 0x00, 0x00, 0x09, 0x15, 0x17, 0x15, 0x09 ; ю - 0x40 + DB 0x00, 0x00, 0x06, 0x08, 0x0e, 0x09, 0x16 ; а - 0x41 + DB 0x01, 0x06, 0x08, 0x0e, 0x09, 0x09, 0x06 ; б - 0x42 + DB 0x00, 0x00, 0x09, 0x09, 0x09, 0x1f, 0x10 ; ц - 0x43 + DB 0x00, 0x00, 0x0e, 0x0a, 0x0a, 0x1f, 0x11 ; д - 0x44 + DB 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x1e ; е - 0x45 + DB 0x00, 0x04, 0x0e, 0x15, 0x15, 0x0e, 0x04 ; ф - 0x46 + DB 0x00, 0x00, 0x0f, 0x09, 0x01, 0x01, 0x01 ; г - 0x47 + DB 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11 ; х - 0x48 + DB 0x00, 0x00, 0x11, 0x19, 0x15, 0x13, 0x11 ; и - 0x49 + DB 0x0a, 0x04, 0x11, 0x19, 0x15, 0x13, 0x11 ; й - 0x4a + DB 0x00, 0x00, 0x11, 0x09, 0x07, 0x09, 0x11 ; к - 0x4b + DB 0x00, 0x00, 0x1c, 0x12, 0x12, 0x12, 0x11 ; л - 0x4c + DB 0x00, 0x00, 0x11, 0x1b, 0x15, 0x11, 0x11 ; м - 0x4d + DB 0x00, 0x00, 0x11, 0x11, 0x1f, 0x11, 0x11 ; н - 0x4e + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e ; о - 0x4f + DB 0x00, 0x00, 0x1f, 0x11, 0x11, 0x11, 0x11 ; п - 0x50 + DB 0x00, 0x00, 0x1e, 0x11, 0x1e, 0x14, 0x12 ; я - 0x51 + DB 0x00, 0x00, 0x07, 0x09, 0x07, 0x01, 0x01 ; р - 0x52 + DB 0x00, 0x00, 0x0e, 0x01, 0x01, 0x01, 0x0e ; с - 0x53 + DB 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04 ; т - 0x54 + DB 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0e ; у - 0x55 + DB 0x00, 0x00, 0x15, 0x15, 0x0e, 0x15, 0x15 ; ж - 0x56 + DB 0x00, 0x00, 0x03, 0x05, 0x07, 0x09, 0x07 ; в - 0x57 + DB 0x00, 0x00, 0x01, 0x01, 0x07, 0x09, 0x07 ; ь - 0x58 + DB 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x13 ; ы - 0x59 + DB 0x00, 0x00, 0x0e, 0x11, 0x0c, 0x11, 0x0e ; з - 0x5a + DB 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1f ; ш - 0x5b + DB 0x00, 0x00, 0x07, 0x08, 0x0e, 0x08, 0x07 ; э - 0x5c + DB 0x00, 0x00, 0x15, 0x15, 0x15, 0x1f, 0x10 ; щ - 0x5d + DB 0x00, 0x00, 0x09, 0x09, 0x0e, 0x08, 0x08 ; ч - 0x5e + DB 0x00, 0x00, 0x06, 0x05, 0x0c, 0x14, 0x0c ; ъ - 0x5f + DB 0x09, 0x15, 0x15, 0x17, 0x15, 0x15, 0x09 ; Ю - 0x60 + DB 0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11 ; А - 0x61 + DB 0x1f, 0x11, 0x01, 0x0f, 0x11, 0x11, 0x1f ; Б - 0x62 + DB 0x09, 0x09, 0x09, 0x09, 0x09, 0x1f, 0x10 ; С - 0x63 + DB 0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x1f, 0x11 ; Д - 0x64 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f ; Е - 0x65 + DB 0x04, 0x0e, 0x15, 0x15, 0x15, 0x0e, 0x04 ; Ф - 0x66 + DB 0x1f, 0x11, 0x01, 0x01, 0x01, 0x01, 0x01 ; Г - 0x67 + DB 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 ; Х - 0x68 + DB 0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11 ; И - 0x69 + DB 0x04, 0x15, 0x11, 0x19, 0x15, 0x13, 0x11 ; Й - 0x6a + DB 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 ; К - 0x6b + DB 0x1c, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11 ; Л - 0x6c + DB 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11 ; М - 0x6d + DB 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 ; Н - 0x6e + DB 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; О - 0x6f + DB 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 ; П - 0x70 + DB 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x12, 0x11 ; Я - 0x71 + DB 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x01, 0x01 ; Р - 0x72 + DB 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e ; С - 0x73 + DB 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; Т - 0x74 + DB 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e ; У - 0x75 + DB 0x15, 0x15, 0x15, 0x0e, 0x15, 0x15, 0x15 ; Ж - 0x76 + DB 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f ; В - 0x77 + DB 0x01, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x0f ; Ь - 0x78 + DB 0x11, 0x11, 0x11, 0x13, 0x15, 0x15, 0x13 ; Ы - 0x79 + DB 0x0e, 0x11, 0x10, 0x0c, 0x10, 0x11, 0x0e ; З - 0x7a + DB 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f ; Ш - 0x7b + DB 0x0e, 0x11, 0x10, 0x1c, 0x10, 0x11, 0x0e ; Э - 0x7c + DB 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x10 ; Щ - 0x7d + DB 0x11, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x10 ; Ч - 0x7e + DB 0x1f, 0x15, 0x1f, 0x15, 0x1f, 0x15, 0x1f ; [DEL] - 0x7f diff --git a/MON_r6_291f2b76/io.inc b/MON_r6_291f2b76/io.inc new file mode 100644 index 0000000..2a401a7 --- /dev/null +++ b/MON_r6_291f2b76/io.inc @@ -0,0 +1,132 @@ +; ======================================================= +; Ocean-240.2 +; Computer with FDC variant. +; IO Ports definitions +; +; By Romych 2025-09-09 +; ======================================================= + + IFNDEF _IO_PORTS + DEFINE _IO_PORTS + +; ------------------------------------------------------- +; КР580ВВ55 DD79 +; ------------------------------------------------------- +; Port A - User port A +USR_DD79PA EQU 0x00 + +; Port B - User port B +USR_DD79PB EQU 0x01 + +; Port C - User port C +USR_DD79PC EQU 0x02 + +; Config: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1] +USR_DD79CTR EQU 0x03 + +; ------------------------------------------------------- +; КР1818ВГ93 +; ------------------------------------------------------- +; CMD +FDC_CMD EQU 0x20 + +; TRACK +FDC_TRACK EQU 0x21 + +; SECTOR +FDC_SECT EQU 0x22 + +; DATA +FDC_DATA EQU 0x23 + +; +FDC_WAIT EQU 0x24 + +; Controller port +FLOPPY EQU 0x25 + + +; ------------------------------------------------------- +; КР580ВВ55 DD78 +; ------------------------------------------------------- +; Port A - Keyboard Data +KBD_DD78PA EQU 0x40 + +; Port B - JST3,SHFT,CTRL,ACK,TAPE5,TAPE4,GK,GC +KBD_DD78PB EQU 0x41 + +; Port C - [PC7..0] +KBD_DD78PC EQU 0x42 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +KBD_DD78CTR EQU 0x43 + + +; ------------------------------------------------------- +; КР580ВИ53 DD70 +; ------------------------------------------------------- +; Counter 1 +TMR_DD70C1 EQU 0x60 + +; Counter 2 +TMR_DD70C2 EQU 0x61 + +; Counter 3 +TMR_DD70C3 EQU 0x62 + +; Config: [sc1,sc0][rl1,rl0][m2,m1,m0][bcd] +; sc - timer, rl=01-LSB, 10-MSB, 11-LSB+MSB +; mode 000 - int on fin, +; 001 - one shot, +; x10 - rate gen, +; x11-sq wave +TMR_DD70CTR EQU 0x63 + +; Programable Interrupt controller PIC KR580VV59 +PIC_DD75RS EQU 0x80 +PIC_DD75RM EQU 0x81 + +; ------------------------------------------------------- +; КР580ВВ51 DD72 +; ------------------------------------------------------- +; Data +UART_DD72RD EQU 0xA0 + +; [RST,RQ_RX,RST_ERR,PAUSE,RX_EN,RX_RDY,TX_RDY] +UART_DD72RR EQU 0xA1 + +; ------------------------------------------------------- +; КР580ВВ55 DD17 +; ------------------------------------------------------- +; Port A - VShift[8..1] +SYS_DD17PA EQU 0xC0 + +; Port B - [ROM14,13][REST][ENROM-][A18,17,16][32k] +SYS_DD17PB EQU 0xC1 + +; Port C - HShift[HS5..1,SB3..1] +SYS_DD17PC EQU 0xC2 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +SYS_DD17CTR EQU 0xC3 + +; ------------------------------------------------------- +; КР580ВВ55 DD67 +; ------------------------------------------------------- +; Port A - LPT Data +LPT_DD67PA EQU 0xE0 + +; Port B - [VSU,C/M,FL3..1,COL3..1] +VID_DD67PB EQU 0xE1 + +; Port C - [USER3..1,STB-LP,BELL,TAPE3..1] +DD67PC EQU 0xE2 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +DD67CTR EQU 0xE3 + + ENDIF diff --git a/MON_r6_291f2b76/m_vars.inc b/MON_r6_291f2b76/m_vars.inc new file mode 100644 index 0000000..74281bd --- /dev/null +++ b/MON_r6_291f2b76/m_vars.inc @@ -0,0 +1,112 @@ +; ======================================================= +; Ocean-240.2 +; Module M_VARS - Monitor variables +; RAM Range: 0xBA09-0xBFFF +; +; Disassembled by Romych 2026-02-18 +; ======================================================= + + IFNDEF _M_VARS + DEFINE _M_VARS + + MODULE M_VARS + ORG 0xbf00 + +buffer: + DS 128 ; bf00 + DS 64 ; bf80 +stor_sp: + DS 14 ; bfc0 +stack_2: + DS 2 ; bfce +stor_de: +stor_e: + DS 1 ; bfd0 +stor_d + DS 1 ; bfd1 +stor_bc: +stor_c: + DS 1 ; bfd2 +stor_b: + DS 1 ; bfd3 + DS 2 ; bfd4 +stor_af: +stor_f: + DS 1 ; bfd6 +stor_a: + DS 1 ; bfd7 +stack_0: + DS 1 ; bfd8 +stor_s: + DS 1 ; bfd9 +store_hl + DS 1 ; bfda +stor_m + DS 1 ; bfdb +start_jp + DS 1 ; bfdc +store_pc: + DS 1 ; bfdd +stor_p: + DS 1 ; bfde +esc_mode: + DS 1 ; bfdf +esc_cmd: + DS 1 ; bfe0 +esc_param_cnt: + DS 1 ; bfe1 +esc_param: + DS 10 ; bfe2 +screen_mode: + DS 1 ; bfec +cursor_row: + DS 1 ; bfed +cursor_col: + DS 1 ; bfee +curr_color: + DS 2 ; bfef +row_shift: + DS 1 ; bff1 +codepage: + DS 1 ; bff2 +cur_palette: + DS 1 ; bff3 +beep_period: + DS 2 ; bff4 +beep_duration: + DS 2 ; bff6 +pix_shift: + DS 1 ; bff8 +strobe_state: + DS 1 ; bff9 +ul_var0: + DS 1 ; bffa +ul_var1: + DS 1 ; bffb +ul_var2: + DS 1 ; bffc +ul_var3: + DS 1 ; bffd +free_vars: + DS 1 ; bffe + DS 1 ; bfff + + ; ASSERT stack_top = 0xbfb8 + ; ASSERT stack = 0xbf00 + ; ASSERT hrg = 0xbf88 + ; ASSERT rst_hl_save = 0xbfc6 + ; ASSERT rst_ret_addr = 0xbfcb + ; ASSERT stack_0 = 0xbfd2 + ; ASSERT esc_mode = 0xbfd9 + ; ASSERT screen_mode = 0xbfe6 + ; ASSERT mc_stored_key = 0xbffd + + ; DISPLAY " esc_mode is: ", esc_mode + ; DISPLAY " esc_mode is: ", esc_mode + ; DISPLAY " rst_ret_addr is: ", rst_ret_addr + ; DISPLAY " tstack_top is: ", tstack_top + ; DISPLAY " mc_stored_key is: ", mc_stored_key + + ENDMODULE + + ENDIF diff --git a/MON_r6_291f2b76/mon_entries.inc b/MON_r6_291f2b76/mon_entries.inc new file mode 100644 index 0000000..a257a56 --- /dev/null +++ b/MON_r6_291f2b76/mon_entries.inc @@ -0,0 +1,35 @@ +; ====================================================== +; Ocean-240.2 +; +; Monitor r6 entries to compile CP/M modules +; +; By Romych 2026-02-18 +; ====================================================== + + IFNDEF _MON_ENTRY + DEFINE _MON_ENTRY + + MODULE MON_ENTRY + +mon_init EQU 0xe000 +mon_cold_start EQU 0xe003 +mon_con_status EQU 0xe006 +mon_con_in EQU 0xe009 +mon_con_out EQU 0xe00c +mon_serial_in EQU 0xe00f +mpn_serial_out EQU 0xe012 +mon_char_print EQU 0xe015 +mon_tape_read EQU 0xe018 +mon_tape_write EQU 0xe01b +mon_ram_disk_read EQU 0xe01e +mon_ram_disk_write EQU 0xe021 +mon_res_f1 EQU 0xe024 +mon_res_f2 EQU 0xe027 +mon_tape_wait EQU 0xe02a +mon_tape_detect EQU 0xe02d +mon_read_floppy EQU 0xe030 +mon_write_floppy EQU 0xe033 + + ENDMODULE + + ENDIF diff --git a/MON_r6_291f2b76/monitor.asm b/MON_r6_291f2b76/monitor.asm new file mode 100644 index 0000000..15325f7 --- /dev/null +++ b/MON_r6_291f2b76/monitor.asm @@ -0,0 +1,4933 @@ +; ====================================================== +; Ocean-240.2 +; Monitor r7 +; crc32: 93bd95db +; +; Disassembled by Romych 2026-02-16 +; ====================================================== + + DEVICE NOSLOT64K + + INCLUDE "io.inc" + INCLUDE "equates.inc" + INCLUDE "ram.inc" + INCLUDE "bios_entries.inc" + + OUTPUT mon_E000.bin + + + MODULE MONITOR + + ORG 0xe000 + +; ------------------------------------------------------ +; Monitor Entry points +; ------------------------------------------------------ + +mon_start: JP m_start ; E000 +mon_cold_start: JP m_cold_start ; E003 +mon_con_status: JP m_con_status ; E006 +mon_con_in: JP m_con_in ; E009 +mon_con_out: JP m_con_out ; E00C +mon_serial_in: JP m_serial_in ; E00F +mon_serial_out: JP m_serial_out ; E012 +mon_char_print: JP m_char_print ; E015 +mon_tape_read: JP m_tape_read ; E018 +mon_tape_write: JP m_tape_write ; E01B +mon_ram_disk_read: JP m_ramdisk_read ; E01E +mon_ram_disk_write: JP m_ramdisk_write ; E021 +mon_tape_read_ram: JP m_tape_read_ram ; E024 +mon_tape_write_ram: JP m_tape_write_ram ; E027 +mon_tape_wait: JP m_tape_wait ; E02A +mon_tape_detect: JP m_tape_blk_detect ; E02D +mon_read_floppy: JP m_read_floppy ; E030 +mon_write_floppy: JP m_write_floppy ; E033 + + +; ------------------------------------------------------ +; Init system devices +; ------------------------------------------------------ +m_start: + DI + LD A, 10000000b ; DD17 all ports to out + OUT (SYS_DD17CTR), A ; VV55 Sys CTR + OUT (DD67CTR), A ; VV55 Video CTR + + ; init_kbd_tape + LD A, 010010011b + OUT (KBD_DD78CTR), A + + LD A, 01111111b ; VSU=0, C/M=1, FL=111, COL=111 + OUT (VID_DD67PB), A ; color mode + LD A, 00000001b + OUT (SYS_DD17PB), A ; Access to VRAM + LD B, 0x0 ; TODO: replace to LD HL, 0x3f00 LD B,L + LD HL, 0x3f00 + LD A, H + ADD A, 0x41 ; A=128 0x80 + + ; Clear memory from 0x3F00 to 0x7FFF +.fill_video: + LD (HL), B + INC HL + CP H + JP NZ, .fill_video + + ;XOR A + LD A, 0 + OUT (SYS_DD17PB), A ; Disable VRAM + LD A, 00000111b + OUT (SYS_DD17PC), A ; pix shift to 7 + LD (M_VARS.pix_shift), A + + XOR A + LD (M_VARS.screen_mode), A + LD (M_VARS.row_shift), A + + ; Set color mode and palette + LD (M_VARS.curr_color+1), A + CPL + LD (M_VARS.curr_color), A + LD A, 00000011b + LD (M_VARS.cur_palette), A + ; VSU=0, C/M=1, FL=000, COL=011 + ; color mode, black border + ; 00-black, 01-red, 10-purple, 11-white + LD A, 01000011b + OUT (VID_DD67PB), A + + ; config LPT + LD A, 0x4 + OUT (DD67PC), A ; bell=1, strobe=0 + LD (M_VARS.strobe_state), A ; store strobe + LD HL, 1024 ; 683us + LD (M_VARS.beep_period), HL + LD HL, 320 ; 213us + LD (M_VARS.beep_duration), HL + +conf_uart: + ; Config UART + LD A, 11001110b + OUT (UART_DD72RR), A + LD A, 00100101b + OUT (UART_DD72RR), A + + ; Config Timer#1 for UART clock + LD A, 01110110b ; tmr#1, load l+m bin, sq wave + OUT (TMR_DD70CTR), A + + ; 1.5M/20 = 75kHz + LD A, 20 + OUT (TMR_DD70C2), A + XOR A + OUT (TMR_DD70C2), A +conf_pic: + ; Config PIC + LD A,00010010b ; ICW1 edge trigger, interval 8, sin... + OUT (PIC_DD75RS), A + XOR A + OUT (PIC_DD75RM), A ; ICW2 + CPL + OUT (PIC_DD75RM), A ; ICW3 no slave + LD A,00100000b + OUT (PIC_DD75RS), A ; Non-specific EOI command, End of I... + LD A, PIC_POLL_MODE + OUT (PIC_DD75RS), A ; Poll mode, poll on next RD + ; Config KBD + LD A, 0x80 + OUT (KBD_DD78PC), A ; TODO: - Check using this 7th bit + NOP + NOP + XOR A + OUT (KBD_DD78PC), A + + ; Init cursor + LD SP, M_VARS.stor_de + CALL m_draw_cursor + + + ; Init BIOS entry + LD HL, M_VARS.stor_sp + LD (M_VARS.stack_0), HL + + LD A, JP_OPCODE + LD (RST1), A + + LD HL, m_rst1_handler + LD (RST1_handler_addr), HL + + ; Beep + LD C, ASCII_BELL + CALL m_con_out +jump_bios: + ; If CP/M BIOS exists, jump to it + LD A, (BIOS.boot_f) + CP JP_OPCODE + JP Z, BIOS.boot_f + + ; No CP/M, Go to monitor + LD HL, msg_hw_mon + CALL m_out_strz + JP m_cold_start + +; -------------------------------------------------- +; Output ASCIIZ string +; Inp: HL -> string +; -------------------------------------------------- +m_out_strz: + LD C, (HL) + LD A, C + OR A + RET Z + CALL m_con_out + INC HL + JP m_out_strz + +msg_hw_mon: + DB "\r\n240/7 MONITOR\r\n", 0 + +; --------------------------------------------------- +reset_m_stack: + LD HL,M_VARS.stor_e + LD SP,HL + CALL get_cmd_letter + INC HL + +; --------------------------------------------------- +; Monitor entry point +; --------------------------------------------------- +m_cold_start: + LD HL,M_VARS.stor_e + LD SP,HL + DI + CALL get_a_ref_sp + CALL get_cmd_letter + LD L,205 + DB 0xdd + PUSH AF + CP ASCII_CR + JP Z,m_cold_start + LD HL,cmd_handlers + LD C,11 + +seek_cmd: + CP (HL) + JP Z,cmd_found + INC HL + INC HL + INC HL + DEC C + JP NZ,seek_cmd + JP reset_m_stack + +cmd_found: + INC HL + ; get cmd handler address + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + ; RET to cold_start + LD DE,m_cold_start + PUSH DE + ; Jump to cmd handler + LD C,2 + JP (HL) + +; --------------------------------------------------- +; Monitor commands handlers table +; --------------------------------------------------- +cmd_handlers: + DB 'D' + DW cmd_D + DB 'F' + DW cmd_F + DB 'G' + DW cmd_G + DB 'L' + DW cmd_L + DB 'M' + DW cmd_M + DB 'R' + DW cmd_R + DB 'S' + DW cmd_S + DB 'W' + DW cmd_W + DB 'X' + DW cmd_X + DB 'B' + DW cmd_B + DB 'A' + DW cmd_A + +; --------------------------------------------------- +; B[n] - Move block n from RAM2 to RAM1 +; --------------------------------------------------- +cmd_B + DEC C + CALL get_address + POP DE + LD HL, tpa_start + CALL m_ramdisk_read + RET + +; --------------------------------------------------- +; A[n] - Move block n from RAM1 to RAM2 +; --------------------------------------------------- +cmd_A: + DEC C + CALL get_address + POP DE + LD HL,256 + CALL m_ramdisk_write + RET + +; --------------------------------------------------- +; D[addr] Dump 128 bytes +; --------------------------------------------------- +cmd_D: + DEC C + CALL get_address + POP HL + LD DE,127 + EX DE,HL + ADD HL,DE + EX DE,HL +d_next_line: + CALL get_a_ref_sp + CALL out_sp_key + CALL out_hex_word +d_next_byte: + CALL out_sp_key + LD A,(HL) + CALL out_hex_byte + CALL next_hl_de + RET C + LD A,L + AND 0x7 + JP NZ,d_next_byte + JP d_next_line + +; --------------------------------------------------- +; F[addr1][addr2]val Fill RAM ares +; --------------------------------------------------- +cmd_F: + INC C + CALL get_address + POP BC + POP DE + POP HL +f_next_b: + LD (HL),C + CALL next_hl_de + JP NC,f_next_b + RET + +; --------------------------------------------------- +; M[addr1][addr2][addr3] - Move mem blk ad +; --------------------------------------------------- +cmd_M: + INC C + CALL get_address + POP BC + POP DE + POP HL +m_next_b: + LD A,(HL) + LD (BC),A + INC BC + CALL next_hl_de + JP NC,m_next_b + RET + +; --------------------------------------------------- +; L - Load Intel HEX from serial interface +; --------------------------------------------------- +cmd_L: + CALL get_key_with_check + JP NC,reset_m_stack + CALL get_a_ref_sp + + ; wait for hex line start +l_wait_colon: + CALL m_serial_in + CP ':' + JP NZ,l_wait_colon + XOR A + LD D,A + CALL read_hex_serial + JP Z,l_exit + ; read line len and addr + LD E,A + CALL read_hex_serial + LD H,A + CALL read_hex_serial + LD L,A + CALL read_hex_serial + LD C,E +l_next_byte: + CALL read_hex_serial + LD (HL),A + INC HL + DEC E + JP NZ,l_next_byte + CALL read_hex_serial + JP NZ,reset_m_stack + JP l_wait_colon + ; read and ignore final 4 hex bytes in las +l_exit: + CALL read_hex_serial + CALL read_hex_serial + CALL read_hex_serial + CALL read_hex_serial + JP NZ,reset_m_stack + RET + +; --------------------------------------------------- +; S[addr] Out and modify ram byte +; --------------------------------------------------- +cmd_S: + CALL s_get_hex_addr + RET C +s_next_byte: + LD A,(HL) + CALL out_hex_byte + CALL get_cmd_letter + DEC L + ; get new value + CALL get_key_with_check + RET C + JP Z,s_next_in + EX DE,HL + CALL hex_keys_to_addr + EX DE,HL + LD (HL),E + RET C +s_next_in: + INC HL + JP s_next_byte + +; --------------------------------------------------- +; X[r] - Out and modify register value +; --------------------------------------------------- +cmd_X: + LD HL,registers_tab + CALL get_key_with_check + JP C,x_ret + LD C,9 +x_seek_reg: + CP (HL) + JP Z,x_reg_found + INC HL + INC HL + INC HL + DEC C + JP NZ,x_seek_reg + JP reset_m_stack +x_reg_found: + CALL out_sp_key + CALL out_reg_value + CALL get_cmd_letter + DEC L + CALL get_key_with_check + RET C + JP Z,reset_m_stack + PUSH BC + ; get new reg value and store + CALL hex_keys_to_addr + LD A,L + LD (DE),A + POP AF + OR A + JP M,x_wreg + INC DE + LD A,H + LD (DE),A +x_wreg: + CALL get_a_ref_sp + RET +x_ret: + CALL get_a_ref_sp +x_next_reg: + XOR A + OR (HL) + RET M + CP 'M' + CALL Z,get_a_ref_sp + CALL out_sp_key + LD C,(HL) + CALL get_key_out + CALL get_cmd_letter + DEC A + CALL out_reg_value + JP x_next_reg + +; --------------------------------------------------- +registers_tab: + DB 'A', LOW(M_VARS.stor_a), 0 + DB 'B', LOW(M_VARS.stor_b), 0 + DB 'C', LOW(M_VARS.stor_c), 0 + DB 'D', LOW(M_VARS.stor_d), 0 + DB 'E', LOW(M_VARS.stor_e), 0 + DB 'F', LOW(M_VARS.stor_f), 0 + DB 'M', LOW(M_VARS.stor_m), 1 + DB 'P', LOW(M_VARS.stor_p), 1 + DB 'S', LOW(M_VARS.stor_s), 1 + DB 0xff + +; ------------------------------------------------------ +; Console status +; Out: A = 0 - not ready +; A = 0xFF - ready (key pressed) +; ------------------------------------------------------ +m_con_status: + IN A, (PIC_DD75RS) ; Read PIC status + NOP + AND KBD_IRQ ; Check keyboard request RST1 + LD A, 0 + RET Z ; no key pressed + CPL + RET ; key pressed + +; ------------------------------------------------------ +; Wait and read data from UART +; Out: A - 7 bit data +; ------------------------------------------------------ +m_serial_in: + IN A, (UART_DD72RR) + AND RX_READY + JP Z, m_serial_in ; wait for rx data ready + IN A, (UART_DD72RD) + AND 0x7f ; leave 7 bits + RET + +; ------------------------------------------------------ +; Read key +; Out: A +; ------------------------------------------------------ +m_con_in: + CALL m_con_status + OR A + JP Z, m_con_in ; wait key + IN A, (KBD_DD78PA) ; get key + AND 0x7f ; reset hi bit, leave 0..127 code + PUSH AF + ; TODO: Check if it is keyboard ACK + ; PC7 Set Hi (ACK?) + LD A, 0x80 + OUT (KBD_DD78PC), A + ; PC7 Set Lo + XOR A + OUT (KBD_DD78PC), A + POP AF + RET + +; ------------------------------------------------------ +; Send data by UART +; Inp: C - data to transmitt +; ------------------------------------------------------ +m_serial_out: + IN A, (UART_DD72RR) + AND TX_READY + JP Z, m_serial_out ; Wait for TX ready + LD A, C + OUT (UART_DD72RD), A + RET + +; ------------------------------------------------------ +; +; ------------------------------------------------------ +read_key_if_pressed: + CALL m_con_status + OR A + RET Z ; ret if no key pressed + JP handle_key_pressed + +; ------------------------------------------------------ +; +; ------------------------------------------------------ +get_a_ref_sp: + CALL get_cmd_letter + DEC C + CALL get_cmd_letter + LD A,(BC) + RET + +; ------------------------------------------------------ +; +; ------------------------------------------------------ +get_cmd_letter: + EX (SP),HL + LD C,(HL) + INC HL + EX (SP),HL + JP get_key_out + +; ------------------------------------------------------ +; Send character to printer +; Inp: C - character +; ------------------------------------------------------ +m_char_print: + ; wait printer ready + IN A, (PIC_DD75RS) + AND PRINTER_IRQ + JP Z, m_char_print + + LD A, C + ;NOP + OUT (LPT_DD67PA), A + ; set LP strobe + LD A, 00010100b + OUT (DD67PC),A + +.wait_lp: + ; wait printer ack + IN A, (PIC_DD75RS) + AND PRINTER_IRQ + JP NZ, .wait_lp + ; remove LP strobe + LD A, 00000100b + OUT (DD67PC), A + RET + + +; ------------------------------------------------------ +; +; ------------------------------------------------------ +out_sp_key: + LD C, ASCII_SP + +; ------------------------------------------------------ +; +; ------------------------------------------------------ +get_key_out: + CALL read_key_if_pressed + + +; ------------------------------------------------------ +; Out char to console +; Inp: C - char +; ------------------------------------------------------ +m_con_out: + PUSH HL + PUSH DE + PUSH BC + CALL m_con_out_int + POP BC + POP DE + POP HL + RET + +; ------------------------------------------------------ +; Out char C to console +; ------------------------------------------------------ +m_con_out_int: + LD DE, M_VARS.esc_mode + LD A, (DE) + DEC A + OR A ; TODO: unused (save 1b 4t) + JP M, m_print_no_esc ; esc_mode=0 - standart print no ESC mode + JP NZ, m_print_at_xy ; esc_mode=2 (graphics) + + ; handle ESC param (esc_mode=1) + INC DE ; TODO: replace to INC E E=0xd3 save 2t + LD A, (DE) + OR A + JP P, get_esc_param + LD A, C + AND 0xf ; convert char to command code + LD (DE), A + INC DE ; TODO: replace to INC E E=0xd3 save 2t + XOR A + LD (DE), A + RET + +get_esc_param: + LD HL, M_VARS.esc_cmd + LD B, (HL) + INC HL + LD A, (HL) + INC A + LD (HL), A + LD E, A + LD D, 0x0 + ADD HL, DE + LD (HL), C + LD HL, esc_params_tab + LD E, B + ADD HL, DE + CP (HL) + RET M + ; ----------------- + LD A, (M_VARS.esc_cmd) + AND 0xf + CP 0xf + JP Z, .l1 + CP 0xb + LD C, 0x5 + JP Z, .l2 + CP 0x4 + JP P, .l6 + +.l1: + LD C, 0x4 + +.l2: + LD HL, M_VARS.esc_param + LD D, H + LD E, L + +.l3: + LD A, (HL) + CP ':' + JP M, .l4 + SUB 0x7 + +.l4: + AND 0xf + ADD A, A + ADD A, A + ADD A, A + ADD A, A + LD B, A + INC HL + LD A, (HL) + CP ':' + JP M, .l5 + SUB 0x7 + +.l5: + AND 0xf + OR B + INC HL + LD (DE), A + INC DE + DEC C + JP NZ, .l3 + +.l6: + LD HL, M_VARS.esc_cmd + LD A, (HL) + AND 0xf + LD E, A + DEC HL + OR A + LD (HL), 0x2 + RET Z + LD D, 0x0 + LD (HL), D + DEC DE + LD HL, esc_handler_tab + ADD HL, DE + ADD HL, DE + LD E, (HL) + INC HL + LD D, (HL) + EX DE, HL + CP 0x4 + JP P, .no_draw_fn + LD A, (M_VARS.screen_mode) + AND 0x7 + JP NZ, esc_exit +.no_draw_fn: + LD DE, esc_exit + PUSH DE + JP (HL) +esc_exit: + XOR A + LD (M_VARS.esc_mode), A + RET + + +; -------------------------------------------------- +; Count of parameters for ESC commands +; -------------------------------------------------- +esc_params_tab: + DB 4, 8, 8, 4, 1, 2, 1, 1 + DB 1, 1, 1, 10, 1, 1, 1, 8 + +esc_handler_tab: + DW esc_draw_fill_rect ;8 1x1y1x2y2m + DW esc_draw_line ;8 2x1y1x2y2 + DW esc_draw_dot ;4 3xxyy + DW esc_set_color ;1 4N N=1..4 + DW esc_set_cursor ;2 5rc r-Row, c-Col + DW esc_set_vmode ;1 6m m-mode: + ; C 0 - 40x25 cursor on + ; M 1,2 - 64x25 cursor on + ; M 3 - 80x25 cursor on + ; C 4 - 40x25 cursor off + ; M 5,6 - 64x25 cursor off + ; M 7 - 80x25 cursor off + ; M 8 - 20rows mode + ; 9 - cursor off + ; 10 - cursor on + DW esc_set_charset ;1 7n where n is: + ; 0 - LAT Both cases + ; 1 - RUS Both cases + ; 2 - LAT+RUS Upper case + DW esc_set_palette ;1 8c c - Foreground+Backgound + DW esc_set_cursor2 ;1 9xy + DW esc_print_screen ;1 : + DW esc_draw_circle ;10 ;xyraxay X,Y, Radius, aspect ratio X, aspect ratio Y + DW esc_unimpl ;1 < + DW esc_unimpl ;1 = + DW esc_unimpl ;1 > + DW esc_set_beep ;8 ?ppdd pp-period (word), dd - duration (word) + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_unimpl: + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_set_beep: + ; param byte 1+2 -> period + LD DE, M_VARS.esc_param + LD A, (DE) + LD H, A + INC DE + LD A, (DE) + LD L, A + LD (M_VARS.beep_period), HL + ; param byte 3+4 -> duration + INC DE + LD A, (DE) + LD H, A + INC DE + LD A, (DE) + LD L, A + LD (M_VARS.beep_duration), HL + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_set_cursor2: + POP DE + XOR A + LD (M_VARS.esc_mode), A + LD A, (M_VARS.screen_mode) + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_print_screen: + LD A, (M_VARS.screen_mode) + AND 00000111b + RET NZ ; ret if not 0-3 mode + LD DE, 0x30ff + CALL m_print_hor_line + DEC E + LD D, 0xf0 + +.chk_keys: + CALL m_con_status + OR A + JP Z, .no_keys + CALL m_con_in + CP ASCII_ESC + RET Z + +.no_keys: + CALL m_print_hor_line + DEC E + JP NZ, .chk_keys + LD D, 0xe0 ; 224d + CALL m_print_hor_line + RET + +; ------------------------------------------------------ +; Print line to printer +; D - width +; ------------------------------------------------------ +m_print_hor_line: + LD HL, cmd_esc_set_X0 + + ; Set printer X coordinate = 0 + CALL m_print_cmd + LD HL, 4 + LD (M_VARS.ul_var0), HL ; Set start coord X = 4 + LD B, 0x0 ; TODO: LD B, H (save 1b 3t) + +.print_next_col: + LD C, 0x0 + ; 1 + CALL m_get_7vpix + AND D + CALL NZ, m_print_vert_7pix + LD HL, (M_VARS.ul_var0) + INC HL + + ; inc X + LD (M_VARS.ul_var0), HL + LD C, 0x1 + ; 2 + CALL m_get_7vpix + AND D + CALL NZ, m_print_vert_7pix + LD HL, (M_VARS.ul_var0) + INC HL + ; inc X + LD (M_VARS.ul_var0), HL + INC B + LD A, B + CP 236 + JP C, .print_next_col + LD HL, cmd_esc_inc_Y2 + CALL m_print_cmd + RET + +; ------------------------------------------------------ +; Send command to printer +; Inp: HL -> command bytes array +; ------------------------------------------------------ +m_print_cmd: + PUSH BC +.print_nxt: + LD A, (HL) + CP ESC_CMD_END + JP Z, .cmd_end + LD C, A + CALL m_char_print + INC HL + JP .print_nxt +.cmd_end: + POP BC + RET + +; ------------------------------------------------------ +; Print 7 vertical pixels to printer +; Inp: A - value to print +; ------------------------------------------------------ +m_print_vert_7pix: + PUSH AF + ; Set coordinate X to 0 + LD HL, cmd_esc_set_X + CALL m_print_cmd + LD HL, (M_VARS.ul_var0) + LD C,H + CALL m_char_print + LD C,L + CALL m_char_print + ; Set column print mode + LD HL, cmd_esc_print_col + CALL m_print_cmd + POP AF + ; Print 7 vertical pixels + LD C, A + CALL m_char_print + RET + +; ------------------------------------------------------ +; Control codes for printer УВВПЧ-30-004 +; ------------------------------------------------------ +; Zn - Increment Y coordinate +cmd_esc_inc_Y2: + DB ASCII_ESC + DB 'Z' + DB 2h + DB ESC_CMD_END + +; Xnn - Set X coordinate +cmd_esc_set_X0: + DB ASCII_ESC + DB 'X' + DB 0h ; 0..479 + DB 0h + DB ESC_CMD_END + +; ------------------------------------------------------ +; X - Start on "Set X coordinate" command +; ------------------------------------------------------ +cmd_esc_set_X: + DB ASCII_ESC + DB 'X' + DB ESC_CMD_END + +; O - Column print (vertical 7 bit) +cmd_esc_print_col: + DB ASCII_ESC + DB 'O' + DB ESC_CMD_END + +; ------------------------------------------------------ +; Get 7 vertical pixels from screen +; Inp: C - sheet +; Out: A - byte +; ------------------------------------------------------ +m_get_7vpix: + LD A, (M_VARS.row_shift) + ADD A, B + ADD A, 19 ; skip first 20pix + LD L, A + PUSH DE + PUSH BC + LD A, E + +.calc_pix_no: + AND 0x7 + LD B, A + LD A, E + ; calc hi addr + RRA ; /8 + RRA + RRA + AND 0x1f + ADD A, A ; *2 + ADD A, 64 ; bytes per row + LD H, A + ; select sheet 0|1 + LD A, C + AND 0x1 + ADD A, H + LD H, A + ; HL = pix addr, turn on VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + LD E, (HL) ; read pixel + INC H ; HL += 512 + INC H + LD D, (HL) ; read pixel row+1 + + ; turn off VRAM access + ;v8 XOR A + LD A, 0 + OUT (SYS_DD17PB), A +.for_all_pix: + DEC B + JP M, .all_shifted + ; shift pixels D >> [CF] >> E + LD A, D + RRA + LD D, A + LD A, E + RRA + LD E, A + JP .for_all_pix +.all_shifted: + LD A, E + LD D, 0 + RRA + JP NC,.not_1_1 + LD D,00110000b +.not_1_1: + RRA + JP NC, .not_1_2 + LD A, D + OR 11000000b + LD D, A +.not_1_2: + LD A, D + POP BC + POP DE + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_set_palette: + LD A, (M_VARS.esc_param) + AND 00111111b ; bgcol[2,1,0],pal[2,1,0] + LD (M_VARS.cur_palette), A + LD B, A + LD A, (M_VARS.screen_mode) + AND 00000011b + LD A, 0x0 + JP NZ, .no_colr + LD A, 0x40 + +.no_colr: + OR B + OUT (VID_DD67PB), A + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_set_charset: + LD A, (M_VARS.esc_param) + AND 0x3 ; charset 0..3 + LD (M_VARS.codepage), A + RET + +; ------------------------------------------------------ +; Get address for draw symbol glyph +; Inp: A - ascii code +; Out: HL -> glyph offset +; ------------------------------------------------------ +m_get_glyph: + LD L, A ; L = ascii code + LD E, A ; E = ascii code + XOR A + LD D, A + LD H, A + ; HL = DE = ascii code + ADD HL, HL + ADD HL, DE + ADD HL, HL + ADD HL, DE + ; HL = A * 7 + LD A, E ; A = A at proc entry + CP '@' + ; First 64 symbols is same for all codepages + JP M, .cp_common + LD A, (M_VARS.codepage) + OR A + ; cp=0 - Latin letters + JP Z, .cp_common + DEC A + ; cp=1 - Russian letters + JP Z, .cp_rus + ; cp=2 - 0x40..0x5F - displayed as Lat + ; 0x60 - 0x7F - displayed as Rus + LD A, E + CP 0x60 + JP M, .cp_common +.cp_rus: + LD DE, 448 ; +448=64*7 Offset for cp1 + ADD HL, DE + +.cp_common: + LD DE, m_font_cp0-224 ; m_font_cp0-32*7 + ADD HL, DE ; add symbol glyph offset + RET + +; -------------------------------------------------- +; Console output +; Inp: C - char +; -------------------------------------------------- +m_print_no_esc: + LD A, C + AND 0x7f + CP 0x20 + JP M, m_handle_esc_code + CALL m_get_glyph + EX DE, HL + LD A, (M_VARS.screen_mode) + AND 0x3 + JP NZ, mp_mode_64 + CALL calc_addr_40 + LD A, 0x1 + OUT (SYS_DD17PB), A + EX DE, HL + LD A, B + OR B + JP Z, mpn_l1 + DEC B + JP Z, mpn_l2 + DEC B + JP Z, mpn_l4 + JP mpn_l6 + +mpn_l1: + XOR A + LD (DE), A + INC D + LD (DE), A + DEC D + INC E + +mpn_l1_1: + LD A, (M_VARS.curr_color) + AND (HL) + LD B, A + LD A, (DE) + AND 0xc0 + OR B + LD (DE), A + LD A, (M_VARS.curr_color+1) + AND (HL) + LD B, A + INC D + LD A, (DE) + AND 0xc0 + OR B + LD (DE), A + DEC D + INC HL + INC E + DEC C + JP NZ, mpn_l1_1 + JP mpn_clos_vram + +mpn_l2: + XOR A + LD (DE), A + INC D + LD (DE), A + DEC D + DEC D + LD (DE), A + DEC D + LD (DE), A + INC D + INC D + INC E + +mpn_l3: + LD A, (M_VARS.curr_color+1) + AND (HL) + RRCA + RRCA + LD (M_VARS.ul_var3), A + LD A, (M_VARS.curr_color) + AND (HL) + RRCA + RRCA + LD (M_VARS.ul_var2), A + AND 0xf + LD B, A + LD A, (DE) + AND 0xf0 + OR B + LD (DE), A + LD A, (M_VARS.ul_var3) + AND 0xf + LD B, A + INC D + LD A, (DE) + AND 0xf0 + OR B + LD (DE), A + DEC D + LD A, (M_VARS.ul_var3) + AND 0xc0 + LD B, A + DEC D + LD A, (DE) + AND 0x3f + OR B + LD (DE), A + LD A, (M_VARS.ul_var2) + AND 0xc0 + LD B, A + DEC D + LD A, (DE) + AND 0x3f + OR B + LD (DE), A + INC D + INC D + INC HL + INC E + DEC C + JP NZ, mpn_l3 + JP mpn_clos_vram + +mpn_l4: + XOR A + LD (DE), A + INC D + LD (DE), A + DEC D + DEC D + LD (DE), A + DEC D + LD (DE), A + INC D + INC D + INC E + +mpn_l5: + LD A, (M_VARS.curr_color+1) + AND (HL) + RRCA + RRCA + RRCA + RRCA + LD (M_VARS.ul_var3), A + LD A, (M_VARS.curr_color) + AND (HL) + RRCA + RRCA + RRCA + RRCA + LD (M_VARS.ul_var2), A + AND 0x3 + LD B, A + LD A, (DE) + AND 0xfc + OR B + LD (DE), A + LD A, (M_VARS.ul_var3) + AND 0x3 + LD B, A + INC D + LD A, (DE) + AND 0xfc + OR B + LD (DE), A + DEC D + LD A, (M_VARS.ul_var3) + AND 0xf0 + LD B, A + DEC D + LD A, (DE) + AND 0xf + OR B + LD (DE), A + LD A, (M_VARS.ul_var2) + AND 0xf0 + LD B, A + DEC D + LD A, (DE) + AND 0xf + OR B + LD (DE), A + INC D + INC D + INC HL + INC E + DEC C + JP NZ, mpn_l5 + JP mpn_clos_vram + +mpn_l6: + DEC D + XOR A + LD (DE), A + DEC D + LD (DE), A + INC D + INC E + +mpn_l7: + LD A, (M_VARS.curr_color+1) + AND (HL) + RLCA + RLCA + LD B, A + LD A, (DE) + AND 0x3 + OR B + LD (DE), A + LD A, (M_VARS.curr_color) + AND (HL) + RLCA + RLCA + LD B, A + DEC D + LD A, (DE) + AND 0x3 + OR B + LD (DE), A + INC D + INC HL + INC E + DEC C + JP NZ, mpn_l7 + INC D + +mpn_clos_vram: + LD A, 0x0 + OUT (SYS_DD17PB), A + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_rt: + INC HL + LD A, (HL) ; a = col + ADD A, 1 ; col+1 + AND 0x3f ; screen column 0..63 + LD (HL), A ; save new col + CP 40 + DEC HL + RET M ; Return if no wrap + +m40_wrap_rt: + INC HL + XOR A + LD (HL), A + DEC HL + LD A, (M_VARS.screen_mode) + AND 0x08 ; screen_mode=8? + JP NZ, m2_lf + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_lf: + LD A, (HL) + ADD A, 11 + CP 250 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_bksp: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A + AND 0x3f ; A=0..63 + CP 0x3f + JP Z, .wrap + LD (HL), A + DEC HL + RET + +.wrap: + LD A, 39 + LD (HL), A + DEC HL + ; and cursor up + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_up: + LD A, (HL) + SUB 11 ; 10 rows per symbol + JP NC, .up_no_minus + LD A, 242 ; wrap to bottom +.up_no_minus: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor right 8 pos) 20rows mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m20_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x3f ; wrap A=0..63 + LD (HL), A + CP 40 + DEC HL + RET M ; ret if column <40 + JP m40_wrap_rt ; or wrap to next line + +; -------------------------------------------------- +; Calculate VRAM address in 40 column mode +; -------------------------------------------------- +calc_addr_40: + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + CP 0x4 + LD B, A + JP M, .l2 + AND 0x3 + LD B, A + LD A, H + OR A + RRA + OR A + RRA + LD C, A + LD H, 0x6 + XOR A +.l1: + ADD A, H + DEC C + JP NZ, .l1 + ADD A, B +.l2: + ADD A, B + ADD A, 0x42 + LD H, A + LD C, 0x7 + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +m2_lf: + LD A, (HL) + ADD A, 11 + CP 15 + JP NC, .lf_nowr + LD (HL), A + RET + +.lf_nowr: + LD A, (M_VARS.row_shift) + LD L, A + ADD A, 11 + LD E, A + LD C, 8 + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.cas_l5: + LD B, 0x40 + LD H, 0x40 ; TODO: LD H, B save 1b 3t + LD D, H + +.cas_l6: + LD A, (DE) + LD (HL), A + INC H + INC D + DEC B + JP NZ, .cas_l6 + INC L + INC E + DEC C + JP NZ, .cas_l5 + LD C, 11 + LD A, (M_VARS.row_shift) + ADD A, 8 + LD E, A + +.cas_l7: + LD B, 0x40 + LD D, 0x40 ; TODO: LD D, B save 1b 3t + XOR A + +.cas_l8: + LD (DE),A + INC D + DEC B + JP NZ,.cas_l8 + INC E + DEC C + JP NZ,.cas_l7 + LD A,0x0 + OUT (SYS_DD17PB),A + RET + + +; --------------------------------------------------- +; Handle ASCII_BS (cursor left) in 20row mode +; --------------------------------------------------- +m20_bksp: + INC HL + LD A, (HL) + OR A + DEC HL + RET Z + + INC HL + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x3f + LD (HL), A + DEC HL + RET + +; --------------------------------------------------- +; Print symbol in 64x25 mode +; --------------------------------------------------- +mp_mode_64: + CP 0x3 + JP Z, mp_mode_80 + PUSH AF + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + ADD A, 0x40 + LD H, A + LD C, 0x7 + POP AF + CP 0x2 + JP Z, m64_put_vram + LD A, 0x1 + OUT (SYS_DD17PB), A + EX DE, HL + XOR A + LD (DE), A + INC E + +m64_next_row: + LD A, (HL) + ADD A, A + LD (DE), A + INC HL + INC E + DEC C + JP NZ, m64_next_row + LD A, 0x0 + OUT (SYS_DD17PB), A + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_rt: + INC HL + LD A, (HL) + ADD A, 0x1 + AND 0x3f + LD (HL), A + DEC HL + RET NZ + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_lf: + LD A, (HL) + ADD A, 11 + CP 0xfa + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Scroll Up for 10 rows +; -------------------------------------------------- +scroll_up: + LD A, (M_VARS.row_shift) + ADD A, 11 + OUT (SYS_DD17PA), A ; Scroll via VShift register + LD (M_VARS.row_shift), A ; store new VShift value + ; calc bottom 16 rows address in VRAM + LD HL, 0x40f0 ; 240th VRAM byte + ADD A, L + LD L, A + LD C, H + + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + XOR A + LD DE, 0x1040 ; D=16 E=64 (512/8 bytes in row) + +.next_row: + LD H, C + LD B, E + + ; clear 64 bytes (512px in mono or 256px in color mode) +.next_col: + LD (HL), A + INC H ; next column + DEC B + JP NZ, .next_col + INC L ; next row address + DEC D ; row counter - 1 + JP NZ, .next_row + + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_bs: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x3f ; wrap column (0..63) + LD (HL), A + CP 63 + DEC HL + RET NZ + ; cursor up if wrapped + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_up: + LD A, (HL) + SUB 11 + JP NC, .no_wrap + LD A, 242 + +.no_wrap: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor column + 8) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x38 + LD (HL), A + DEC HL + RET NZ ; return if no wrap + ; cursor down if wrap + JP m64_lf + +; -------------------------------------------------- +; Print symbols in 80x25 mode +; -------------------------------------------------- +mp_mode_80: + CALL calc_addr_80 + LD A, 0x1 + OUT (SYS_DD17PB), A + EX DE, HL + LD A, B + OR B + JP Z, m80_l1 + DEC B + JP Z, m80_l3 + DEC B + JP Z, m80_l5 + JP m80_l7 + +m80_l1: + XOR A + LD (DE), A + INC E +m80_l2: + LD B, (HL) + LD A, (DE) + AND 0xc0 + OR B + LD (DE), A + INC HL + INC E + DEC C + JP NZ, m80_l2 + JP m80_l9 +m80_l3: + XOR A + LD (DE), A + DEC D + LD (DE), A + INC D + INC E +m80_l4: + LD A, (HL) + RRCA + RRCA + AND 0x7 + LD B, A + LD A, (DE) + AND 0xf0 + OR B + LD (DE), A + LD A, (HL) + RRCA + RRCA + AND 0xc0 + LD B, A + DEC D + LD A, (DE) + AND 0x1f + OR B + LD (DE), A + INC D + INC HL + INC E + DEC C + JP NZ, m80_l4 + JP m80_l9 +m80_l5: + XOR A + LD (DE), A + DEC D + LD (DE), A + INC D + INC E +m80_l6: + LD A, (HL) + RRCA + RRCA + RRCA + RRCA + AND 0x1 + LD B, A + LD A, (DE) + AND 0xfc + OR B + LD (DE), A + LD A, (HL) + RRCA + RRCA + RRCA + RRCA + AND 0xf0 + LD B, A + DEC D + LD A, (DE) + AND 0x7 + OR B + LD (DE), A + INC D + INC HL + INC E + DEC C + JP NZ, m80_l6 + JP m80_l9 + +m80_l7: + DEC D + XOR A + LD (DE), A + INC E +m80_l8: + LD A, (HL) + RLCA + RLCA + LD B, A + LD A, (DE) + AND 0x1 + OR B + LD (DE), A + INC HL + INC E + DEC C + JP NZ, m80_l8 + INC D + +m80_l9: + LD A, 0x0 + OUT (SYS_DD17PB), A + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_rt: + INC HL + LD A, (HL) + ADD A, 0x1 + AND 0x7f + LD (HL), A + CP 0x50 + DEC HL + RET M + +m80_col_wrap: + INC HL + XOR A + LD (HL), A + DEC HL + ; and move cursor to next row + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_lf: + LD A, (HL) + ADD A, 11 + CP 250 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_bs: + INC HL + LD A, (HL) + SUB 0x1 + AND 0x7f + CP 0x7f + JP Z, .wrap + LD (HL), A + DEC HL + RET +.wrap: + LD A, 0x4f + LD (HL), A + DEC HL + + ; and move cursor to previous line + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_up: + LD A, (HL) + SUB 0xb + JP NC, .wrap + LD A, 0xf2 +.wrap + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor column + 8) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_tab: + INC HL + LD A, (HL) + ADD A, 0x8 + AND 0x7f + LD (HL), A + CP 0x50 + DEC HL + RET M + JP m80_col_wrap + +; -------------------------------------------------- +; Calculate address for cursor pos for 80x25 mode +; Out: HL -> VRAM +; B -> pixel pos in byte +; -------------------------------------------------- +calc_addr_80: + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + CP 0x4 + LD B, A + JP M, ca80_l2 + AND 0x3 + LD B, A + LD A, H + OR A + RRA + OR A + RRA + LD C, A + LD H, 0x3 + XOR A +ca80_l1: + ADD A, H + DEC C + JP NZ, ca80_l1 + ADD A, B +ca80_l2: + ADD A, 0x42 + LD H, A + LD C, 0x7 + RET + +; -------------------------------------------------- +m64_put_vram: + LD A, (M_VARS.cursor_col) + CP 0x40 + JP M, pv_access_vram + LD HL, M_VARS.cursor_row + CALL m_draw_cursor + RET + +pv_access_vram: + LD A, 0x1 + OUT (SYS_DD17PB), A + EX DE, HL + XOR A + LD (DE), A + INC E + +pv_rept: + LD A, (HL) + ADD A, A + LD (DE), A + INC HL + INC E + DEC C + JP NZ, pv_rept + LD A, 0x0 + OUT (SYS_DD17PB), A + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + INC HL + LD A, (HL) + ADD A, 0x1 + CP 0x40 + JP M, pv_end + LD A, 0x40 +pv_end: + LD (HL), A + DEC HL + RET + +; -------------------------------------------------- +; Clear screen and set cursor to 0,0 +; Inp: HL -> cursor position +; -------------------------------------------------- +m_clear_screen: + LD A, (M_VARS.screen_mode) + AND 0x8 + JP NZ, m_clear_20_rows ; for bit 4 is set, clear only 20 rows + ; all in black + LD A, 01111111b + OUT (VID_DD67PB), A ; C/M=1 FL=111 CL=111 All black + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + LD DE, video_ram + EX DE, HL + LD A, H + ADD A, 0x40 ; A=0x80 + LD B, 0 + +.fill_scrn: + LD (HL), B + INC HL + CP H + JP NZ, .fill_scrn ; fill while HL<0x8000 + + EX DE, HL + LD A, (M_VARS.cur_palette) + LD B, A ; B = current palette + LD A, (M_VARS.screen_mode) + AND 0x3 ; color? + LD A, 0x0 + JP NZ, .mono_mode + LD A, 01000000b +.mono_mode: + OR B + ; Restore mode and palette + OUT (VID_DD67PB), A + + ; And set cursor to home position + +; -------------------------------------------------- +; Set cursor to 0,0 and close VRAM access +; Inp: HL -> cursor_row +; -------------------------------------------------- +m_cursor_home: + XOR A + NOP + NOP + LD (HL), A + INC HL + XOR A + LD (HL), A + DEC HL + ;XOR A + LD A, 0 + ; Disable VRAM access + OUT (SYS_DD17PB), A + RET + +; Clear only 20 rows +m_clear_20_rows: + ; take row shift in account + LD A, (M_VARS.row_shift) + LD L, A + LD C, 20 + + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.next_row: + LD H, 0x40 ; HL = 0x4000 + shift_row + LD B, 64 ; 64 bytes at row + XOR A +.next_col: + LD (HL), A + INC H ; next column + DEC B + JP NZ, .next_col + INC L ; next row + DEC C + JP NZ, .next_row + ; Disabe VRAM access + LD A, 0 + OUT (SYS_DD17PB), A + JP m_cursor_home + +; -------------------------------------------------- +; Draw cursor at current cursor position +; if not hidden +; -------------------------------------------------- +m_draw_cursor: + LD A, (M_VARS.screen_mode) + AND 0x4 + RET NZ + LD A, (M_VARS.screen_mode) + AND 0x3 + JP NZ, .dc_mode_64 + EX DE, HL + LD HL, (M_VARS.cursor_row) + LD A, H + CP 0x28 + EX DE, HL + RET P + EX DE, HL + CALL calc_addr_40 + LD A, 0x1 + OUT (SYS_DD17PB), A + LD C, 0x8 + LD A, B + OR B + JP Z, .l1 + DEC B + JP Z, .l2 + DEC B + JP Z, .l3 + JP .l4 + +.l1: + LD A, (HL) + AND 0xc0 + LD B, A + LD A, (HL) + XOR 0x1f + AND 0x1f + OR B + LD (HL), A + INC H + LD A, (HL) + AND 0xc0 + LD B, A + LD A, (HL) + XOR 0x1f + AND 0x1f + OR B + LD (HL), A + DEC H + INC L + DEC C + JP NZ, .l1 + JP .l6 + +.l2: + DEC H + LD A, (HL) + AND 0x3f + LD B, A + LD A, (HL) + XOR 0xc0 + AND 0xc0 + OR B + LD (HL), A + DEC H + LD A, (HL) + AND 0x3f + LD B, A + LD A, (HL) + XOR 0xc0 + AND 0xc0 + OR B + LD (HL), A + INC H + INC H + LD A, (HL) + AND 0xf0 + LD B, A + LD A, (HL) + XOR 0x7 + AND 0x7 + OR B + LD (HL), A + INC H + LD A, (HL) + AND 0xf0 + LD B, A + LD A, (HL) + XOR 0x7 + AND 0x7 + OR B + LD (HL), A + DEC H + INC L + DEC C + JP NZ, .l2 + JP .l6 + +.l3: + DEC H + LD A, (HL) + AND 0xf + LD B, A + LD A, (HL) + XOR 0xf0 + AND 0xf0 + OR B + LD (HL), A + DEC H + LD A, (HL) + AND 0xf + LD B, A + LD A, (HL) + XOR 0xf0 + AND 0xf0 + OR B + LD (HL), A + INC H + INC H + LD A, (HL) + AND 0xfc + LD B, A + LD A, (HL) + XOR 0x1 + AND 0x1 + OR B + LD (HL), A + INC H + LD A, (HL) + AND 0xfc + LD B, A + LD A, (HL) + XOR 0x1 + AND 0x1 + LD (HL), A + DEC H + INC L + DEC C + JP NZ, .l3 + JP .l6 + +.l4: + DEC H + +.l5: + LD A, (HL) + AND 0x3 + LD B, A + LD A, (HL) + XOR 0x7c + AND 0x7c + OR B + LD (HL), A + DEC H + LD A, (HL) + AND 0x3 + LD B, A + LD A, (HL) + XOR 0x7c + AND 0x7c + OR B + LD (HL), A + INC H + INC L + DEC C + JP NZ, .l5 + INC H + +.l6: + EX DE, HL + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +.dc_mode_64: + CP 0x3 + JP Z, .l8 + EX DE, HL + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + CP 0x40 + EX DE, HL + RET P + EX DE, HL + ADD A, 0x40 + LD H, A + LD A, 0x1 + OUT (SYS_DD17PB), A + LD BC, 0x7f08 + +.l7: + LD A, (HL) + XOR B + LD (HL), A + INC L + DEC C + JP NZ, .l7 + EX DE, HL + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +.l8: + EX DE, HL + LD HL, (M_VARS.cursor_row) + LD A, H + CP 0x50 + EX DE, HL + RET P + EX DE, HL + CALL calc_addr_80 + LD C, 0x8 + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, B + OR B + JP Z, .l9 + DEC B + JP Z, .l10 + DEC B + JP Z, .l11 + JP .l12 + +.l9: + LD A, (HL) + AND 0xc0 + LD B, A + LD A, (HL) + XOR 0x1f + AND 0x1f + OR B + LD (HL), A + INC L + DEC C + JP NZ, .l9 + JP .exit + +.l10: + DEC H + LD A, (HL) + AND 0x1f + LD B, A + LD A, (HL) + XOR 0xc0 + AND 0xc0 + OR B + LD (HL), A + INC H + LD A, (HL) + AND 0xf0 + LD B, A + LD A, (HL) + XOR 0x7 + AND 0x7 + OR B + LD (HL), A + INC L + DEC C + JP NZ, .l10 + JP .exit + +.l11: + DEC H + LD A, (HL) + AND 0x7 + LD B, A + LD A, (HL) + XOR 0xf0 + AND 0xf0 + OR B + LD (HL), A + INC H + LD A, (HL) + AND 0xfc + LD B, A + LD A, (HL) + XOR 0x1 + AND 0x1 + OR B + LD (HL), A + INC L + DEC C + JP NZ, .l11 + JP .exit + +.l12: + DEC H +.l13: + LD A, (HL) + AND 0x1 + LD B, A + LD A, (HL) + XOR 0x7c + AND 0x7c + OR B + LD (HL), A + INC L + DEC C + JP NZ, .l13 + INC H + +.exit: + EX DE, HL + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; If ESC character, turn esc_mode ON +; Inp: A - ASCII symbol +; -------------------------------------------------- +m_handle_esc_code: + CP ASCII_ESC + JP NZ, m_handle_control_code + ; turn on ESC mode for next chars + LD HL, M_VARS.esc_mode + LD (HL), 0x1 ; turn on ESC mode + INC HL + LD (HL), 0xff ; esc_cmd = 0xff + RET + +; -------------------------------------------------- +; Handle one byte ASCII control code +; Inp: A - ASCII symbol +; -------------------------------------------------- +m_handle_control_code: + CP ASCII_BELL + JP Z, m_beep + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + PUSH AF + CALL m_draw_cursor + LD A, (M_VARS.screen_mode) + AND 0x08 ; 20-rows mode? + JP Z, handle_cc_common ; jump for normal screen modes + + ; for hidden cursor modes + POP AF + CP ASCII_TAB ; TAB + JP Z, m20_tab + CP ASCII_BS ; BKSP + JP Z, m20_bksp + CP ASCII_CAN ; Cancel + JP Z, m40_rt + CP ASCII_US ; ASCII Unit separator + JP Z, m_clear_20_rows + CP ASCII_LF ; LF + JP Z, m2_lf + CP ASCII_CR ; CR + RET NZ ; ret on unknown + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; Handle cursor for 40x25, 64x25, 80x25 modes +; -------------------------------------------------- +handle_cc_common: + POP AF + CP ASCII_US + JP Z, m_clear_screen + CP ASCII_FF + JP Z, m_cursor_home + PUSH AF + LD A, (M_VARS.screen_mode) + AND 3 ; check for color modes + JP NZ, handle_cc_mono + ; 32x25 text mode + POP AF + CP ASCII_TAB ; cursor right +8 + JP Z, m20_tab + CP ASCII_BS ; cursor left + JP Z, m40_bksp + CP ASCII_CAN ; cursor right + JP Z, m40_rt + CP ASCII_EM ; cursor up + JP Z, m40_up + CP ASCII_SUB + JP Z, m40_lf ; cursor down + CP ASCII_LF + JP Z, m40_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 ; move cursor to first column for CR + DEC HL + RET + +; -------------------------------------------------- +; Handle control chars for 64x25 or 80x25 modes +; -------------------------------------------------- +handle_cc_mono: + LD A, (M_VARS.screen_mode) + CP 0x3 + JP Z, handle_cc_80x25 + CP 0x7 + JP Z, handle_cc_80x25 + AND 0x2 + JP NZ, handle_cc_colr + POP AF + CP ASCII_TAB + JP Z, m64_tab + CP ASCII_BS + JP Z, m64_bs + CP ASCII_CAN + JP Z, m64_rt + CP ASCII_EM + JP Z, m64_up + CP ASCII_SUB + JP Z, m64_lf + CP ASCII_LF + JP Z, m64_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 + DEC HL + RET + +handle_cc_colr: + POP AF + CP ASCII_LF + JP Z, m64_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 + DEC HL + RET + + +; -------------------------------------------------- +; Handle control chars for 80x25 modes +; -------------------------------------------------- +handle_cc_80x25: + POP AF + CP ASCII_TAB + JP Z, m80_tab + CP ASCII_BS + JP Z, m80_bs + CP ASCII_CAN + JP Z, m80_rt + CP ASCII_EM + JP Z, m80_up + CP ASCII_SUB + JP Z, m80_lf + CP ASCII_LF + JP Z, m80_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +m_beep: + LD HL, (M_VARS.beep_duration) + EX DE, HL + LD HL, (M_VARS.beep_period) + LD A, 00110110b ; TMR#0 LSB+MSB Square Wave Generator + OUT (TMR_DD70CTR), A + LD A, L ; LSB + OUT (TMR_DD70C1), A + LD A, H ; MSB + OUT (TMR_DD70C1), A + LD A, (M_VARS.strobe_state) + LD B, A +m_bell_cont: + LD A, D ; DE=duration + OR E + RET Z ; ret if enough + DEC DE + LD A, B + XOR BELL_PIN + LD B, A + OUT (DD67PC), A ; Invert bell pin +m_bell_wait_tmr1: + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; 0x10 + JP NZ, m_bell_wait_tmr1 + LD A, B + XOR BELL_PIN ; Flip pin again + LD B, A + OUT (DD67PC), A +m_bell_wait_tmr2: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP Z,m_bell_wait_tmr2 + JP m_bell_cont + + +; ------------------------------------------------------ +; 5 Set cursor position +; ------------------------------------------------------ +esc_set_cursor: + LD A, (M_VARS.screen_mode) + AND 0x8 + RET NZ + CALL m_draw_cursor + LD DE, M_VARS.esc_param + LD HL, M_VARS.cursor_col + INC DE + LD A, (DE) + SUB 0x20 + LD B, A + LD A, (M_VARS.screen_mode) + CP 0x3 + JP Z, .mode80 + CP 0x7 + JP Z, .mode80 + OR A + JP Z, .mode40 + CP 0x4 + JP Z, .mode40 + LD A, B + CP 0x40 + JP M, .common + LD A, 0x40 + JP .common +.mode40: + LD A, B + CP 40 + JP M, .common + LD A, 40 + JP .common +.mode80: + LD A, B + CP 80 + JP M, .common + LD A, 80 +.common: + LD (HL), A + DEC DE + DEC HL + LD A, (DE) + SUB 32 + CP 22 + JP C, .le_24 + LD A, 22 +.le_24: + LD B, A + ADD A, A + ADD A, A + ADD A, B + ADD A, A + ADD A, B + LD (HL), A + CALL m_draw_cursor + RET + +; ------------------------------------------------------ +; 6n Set video mode or cursor visibility +; Inp: n is +; 0 - C 32x25 with cursor; 0000 +; 1 - M 64x25 with cursor; 0001 +; 2 - M 64x25 with cursor; 0010 +; 3 - M 80x25 with cursor; 0011 +; 4 - C 32x25 no cursor; 0100 +; 5 - M 64x25 no cursor; 0101 +; 6 - M 64x25 no cursor; 0110 +; 7 - M 80x25 no cursor; 0111 +; 8 - M 20rows mode 1000 +; 9 - hide cursor 1001 +; 10 - show cursor 1010 +; ------------------------------------------------------ +esc_set_vmode: + LD HL, M_VARS.screen_mode + LD A, (M_VARS.cur_palette) + LD B, A + LD A, (M_VARS.esc_param) + LD C, A + AND 0x8 + LD A, C + JP Z, .no_20_mode + LD A, 0x8 +.no_20_mode: + AND 0xf + LD (HL), A + CP 0x4 + JP Z, .m32x25c + AND 0x3 + LD A, 0x0 + JP NZ, .t_mode +.m32x25c: + LD A, 0x40 +.t_mode: + OR B + OUT (VID_DD67PB), A + LD HL, M_VARS.cursor_row + CALL m_clear_screen + CALL m_draw_cursor + RET + +; ------------------------------------------------------ +; 4n n=1..4 Set drawing color +; ------------------------------------------------------ +esc_set_color: + LD A, (M_VARS.esc_param) +m_set_color: + AND 0x3 + RRA + LD B, A + LD A, 0x0 ; TODO: unused + SBC A, A + LD (M_VARS.curr_color), A + LD A, B + DEC A + CPL + LD (M_VARS.curr_color+1), A + RET + +;--------------------------------------------------- +; Print symbol or print sprite at X,Y coordinates +; Inp: param x,y +; C - character or sprite_no to draw +;--------------------------------------------------- +m_print_at_xy: + LD A,(M_VARS.screen_mode) + AND 0x7 + JP NZ,esc_exit + LD A,C + AND 0x7f + LD C,A + CP 0x20 + JP M,esc_exit + LD HL,M_VARS.esc_param + LD A,(HL) + LD E,A + ADD A,0x8 + JP C,esc_exit + LD (HL),A + INC HL + LD A,0xf7 + CP (HL) + JP C,esc_exit + LD D,(HL) + CALL calc_px_addr + LD A,L + SUB 0x7 + LD L,A + PUSH HL + LD A,C + CALL m_get_glyph + POP DE + LD C,0x7 +.l1: + PUSH HL + LD A,0x1 + OUT (SYS_DD17PB),A + LD L,(HL) + LD H,0x0 + LD A,B + OR A + JP Z,.l3 +.l2: + ADD HL,HL + DEC A + JP NZ,.l2 +.l3: + EX DE,HL + PUSH BC + LD A,(M_VARS.curr_color) + CPL + LD B,A + LD A,(HL) + XOR B + OR E + XOR B + LD (HL),A + INC H + INC H + LD A,(HL) + XOR B + OR D + XOR B + LD (HL),A + DEC H + LD A,(M_VARS.curr_color+1) + CPL + LD B,A + LD A,(HL) + XOR B + OR E + XOR B + LD (HL),A + INC H + INC H + LD A,(HL) + XOR B + OR D + XOR B + LD (HL),A + DEC H + DEC H + DEC H + INC L + EX DE,HL + POP BC + LD A,0x0 + OUT (SYS_DD17PB),A + POP HL + INC HL + DEC C + JP NZ,.l1 + RET + +; -------------------------------------------------- +; Calculate address of pixel in Video RAM +; Inp: DE - Y, X +; Out: HL - address +; B - offset in byte +; -------------------------------------------------- +calc_px_addr: + ; take into account the vertical displacement + LD A, (M_VARS.row_shift) + SUB D + DEC A + LD L, A + + LD A, E + AND 0x07 ; X mod 8 - offset in byte + LD B, A + + LD A, E + RRA + RRA + AND 00111110b + ADD A, 0x40 ; VRAM at 0x4000 + LD H, A + RET + + +;--------------------------------------------------- +; Draw Filled Rectange +; Inp: esc param X1,Y2,X2,Y2 +; -------------------------------------------------- +esc_draw_fill_rect: + LD HL, M_VARS.esc_param+3 + LD DE, M_VARS.esc_param+1 + LD A, (DE) + LD B, (HL) + CP B + JP NC, .l1 + LD (HL), A + LD A, B + LD (DE), A +.l1: + DEC DE + DEC HL + LD A, (DE) + LD B, (HL) + CP B + JP C, .l2 + LD (HL), A + LD A, B + LD (DE), A +.l2: + EX DE, HL + LD E, (HL) + INC HL + LD D, (HL) + CALL calc_px_addr + PUSH HL + XOR A +.l3: + SCF + RLA + DEC B + JP P, .l3 + RRA + LD D, A + LD HL, M_VARS.esc_param+2 + LD A, (HL) + AND 0x7 + LD B, A + XOR A +.l4: + SCF + RLA + DEC B + JP P, .l4 + CPL + LD E, A + LD A, (HL) + DEC HL + DEC HL + SUB (HL) + RRCA + RRCA + RRCA + AND 0x1f + LD C, A + INC HL + LD A, (HL) + INC HL + INC HL + SUB (HL) + JP NZ, .l5 + INC A +.l5: + LD B, A + POP HL + LD A, E + LD (M_VARS.esc_param+4), A +.l6: + PUSH DE + PUSH HL + PUSH BC + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, C + OR A + JP NZ, .l8 + LD A, D + OR E +.l7: + LD D, A +.l8: + LD B, D + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + INC H + LD A, C + OR A + JP Z, .l11 + DEC C +.l9: + LD A, (M_VARS.esc_param+4) + JP Z, .l7 +.l10: + LD (HL), E + INC H + LD (HL), D + INC H + DEC C + JP NZ, .l10 + JP .l9 +.l11: + LD A, 0x0 + OUT (SYS_DD17PB), A + POP BC + POP HL + POP DE + INC L + DEC B + JP NZ, .l6 + RET + +;--------------------------------------------------- +; 2x1y1x2y2 Draw Line +;--------------------------------------------------- +esc_draw_line: + LD HL, M_VARS.esc_param + LD E, (HL) ; E=X1 + INC HL + LD D, (HL) ; D=Y1 + INC HL + LD A, (HL) + INC HL + LD H, (HL) ; H=Y2 + LD L, A ; L=X2 + CP E + JP C, .x1_le_x2 + EX DE, HL ; exchange if X1>X2 +.x1_le_x2: + LD (M_VARS.esc_param), HL ; store x1,y1 back + LD A, E + SUB L + LD L, A ; L - width + LD A, D + SUB H + LD H, A ; H - height + PUSH AF + JP NC, .pos_height + ; change sign + CPL + INC A + LD H, A +.pos_height: + EX DE, HL + LD HL, (M_VARS.esc_param) + EX DE, HL + JP Z, height0 + LD A, L + OR A + JP Z, .width0 + LD B, A + POP AF + LD A, 0x0 + ADC A, A + LD (M_VARS.esc_param+4), A + ; HL = E/B height/width + LD E, H + LD C, 16 + LD D, 0 +.next_16: + ADD HL, HL + EX DE, HL + ADD HL, HL + EX DE, HL + LD A, D + JP C, .edl_l4 + CP B + JP C, .edl_l5 +.edl_l4: + SUB B + LD D, A + INC HL +.edl_l5: + DEC C + JP NZ, .next_16 + LD DE, 0x0 + PUSH DE + ; save result at stack + PUSH HL + + LD HL, (M_VARS.esc_param) ; x1,y1 + EX DE, HL + LD C, B + CALL calc_px_addr + ; HL - address, B - offset in byte + ; make mask + LD A, 10000000b +.roll_l: + RLCA + DEC B + JP P, .roll_l + CPL + LD B, A ; b - inv mask + +.edl_l7 + POP DE + EX (SP), HL ; save HL on top of stack + LD A, H + ADD HL, DE + SUB H + CPL + INC A + EX (SP), HL + PUSH DE + PUSH BC + LD C, A + EX DE, HL + + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Access VideoRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + LD A, (M_VARS.esc_param+4) ; sign of delta Y + OR A + JP NZ, .next_down +.next_up: + ; firs byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + DEC H + LD A, C + OR A + JP Z, .is_last + DEC C + ; draw up + DEC L + JP .next_up +.next_down: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; + DEC H + LD A, C + OR A + JP Z, .is_last + DEC C + ; draw down + INC L + JP .next_down +.is_last: + ; Disable VideoRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + POP BC + LD A, B + ; <<1px + SCF + RLA + JP C, .edl_l11 + RLA + INC H + INC H +.edl_l11 + LD B, A + DEC C + JP NZ, .edl_l7 + POP HL + POP HL + RET + +; -------------------------------------------------- +; draw vertical line +; Inp: DE - YX +; L - length +; -------------------------------------------------- +.width0 + LD C, H + CALL calc_px_addr + + ; make pixel mask + LD A, 10000000b +.edl_l13: + RLCA + DEC B + JP P, .edl_l13 + CPL + LD B, A + + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + POP AF + + ; Enable VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + JP C, .next_row_down + +.next_row_up: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next Y + DEC H + LD A, C + OR A + JP Z, close_vram_ret + DEC C + ; dec row + DEC L + JP .next_row_up + +.next_row_down: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next address + DEC H + LD A, C + OR A + JP Z, close_vram_ret + DEC C + ; inc row + INC L + JP .next_row_down + +close_vram_ret: + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; Draw horizontal line +; Inp: DE - YX +; L - length +; -------------------------------------------------- +height0: + POP AF + LD C, L + LD A, L + OR A + JP NZ, .len_ne0 + INC C ; length 1 at least +.len_ne0: + CALL calc_px_addr + ; make pixel mask + LD A, 10000000b +.edl_l19 + RLCA + DEC B + JP P, .edl_l19 + CPL + LD B, A + + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + + ; Enable VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + +.next_col: + ; set 1st byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; set 2nd byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next byte + DEC H + ; next (right) horizontal pixel + LD A, B + SCF + RLA + JP C, .edl_l21 + RLA + INC H + INC H +.edl_l21 + LD B, A + DEC C + JP NZ, .next_col + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; ESC Draw Dot +; -------------------------------------------------- +esc_draw_dot: + LD HL, (M_VARS.esc_param) + EX DE, HL + CALL calc_px_addr + LD A, 0x80 +.l1: + RLCA + DEC B + JP P, .l1 + LD B, A + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, (HL) + XOR B + LD (HL), A + INC H + LD A, (HL) + XOR B + LD (HL), A + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; --------------------------------------------------- +; Draw circle +; Inp: param x,y,radius, aspect_x, aspect_y +; --------------------------------------------------- +esc_draw_circle: + LD A, (M_VARS.esc_param+2) ; radius + LD B, A + OR A + RET Z ; exit ir radius 0 + LD A, 0x7f + CP B + RET M ; exit if radius>127 + + XOR A + LD D, A ; 0 + LD E, B ; r + CALL dc_draw_8px + + LD A, 1 + LD H, A + SUB B + LD C, A + LD A, B + RLCA + LD B, A + LD A, 0x1 + SUB B + LD L, A + CCF ; TODO: unused +.l1: + INC D + LD A, E + CP D + JP Z, dc_draw_8px + CALL dc_draw_8px + LD A, H + ADD A, 0x2 + LD H, A + LD A, L + ADD A, 0x2 + LD L, A + LD A, C + ADD A, H + LD C, A + JP NC, .l1 +.l2: + CCF ; TODO: unused + INC D + DEC E + LD A, D + CP E + JP Z, dc_draw_8px + SUB E + CP 0x1 + RET Z + LD A, E + SUB D + CP 0x1 + JP Z, dc_draw_8px + CALL dc_draw_8px + LD A, H + ADD A, 0x2 + LD H, A + LD A, L + ADD A, 0x4 + LD L, A + JP NC, .l3 + CCF ; TODO: unused +.l3: + LD A, C + ADD A, L + LD C, A + JP NC, .l1 + JP .l2 + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_8px: + PUSH HL + PUSH DE + PUSH BC + PUSH DE + CALL dc_aspect_ratio_1 + LD HL, (M_VARS.esc_param) ; HL=Y,X + CALL dc_draw_4px_bc + POP DE + CALL dc_aspect_ratio2 + LD HL, (M_VARS.esc_param) ; HL=Y,X + CALL dc_draw_4px_cb + POP BC + POP DE + POP HL + XOR A + RET + +; --------------------------------------------------- +; Scale circle axis dy specified aspect ratio +; if aspect_x = 0 C = D else C = D * aspect_x / 256 +; if aspect_y = 0 B = E else B = E * aspect_y / 256 +; --------------------------------------------------- +dc_aspect_ratio_1: + LD HL, (M_VARS.esc_param+3) ; aspect_x -> L, aspect_y -> H + LD A, L + OR A + LD C, D + LD B, E + JP NZ, .dc_ax_ne0 + LD A, H + OR A + JP NZ, .dc_ay_ne0 + RET +.dc_ax_ne0: + LD A, H + LD H, L + LD E, C + CALL dc_mul_e_h + LD C, E + OR A + RET Z +.dc_ay_ne0: + LD H, A + LD E, B + CALL dc_mul_e_h + LD B, E + RET + +; --------------------------------------------------- +; if aspect_x = 0 B = E else B = E * aspect_x / 256 +; if aspect_y = 0 C = D else C = D * aspect_y / 256 +; --------------------------------------------------- +dc_aspect_ratio2: + LD HL, (M_VARS.esc_param+3) ; aspect_x -> L, aspect_y -> H + LD A, L + OR A + LD C, D + LD B, E + JP NZ, .dc_ax_ne0 + LD A, H + OR A + JP NZ, .dc_ay_ne0 + RET +.dc_ax_ne0: + LD A, H + LD H, L + LD E, B + CALL dc_mul_e_h + LD B, E + OR A + RET Z + +.dc_ay_ne0: + LD H, A + LD E, C + CALL dc_mul_e_h + LD C, E + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_mul_e_h: + LD D, 0x0 + LD L, D + ADD HL, HL + JP NC, .l1 + ADD HL, DE +.l1: + ADD HL, HL + JP NC, .l2 + ADD HL, DE +.l2: + ADD HL, HL + JP NC, .l3 + ADD HL, DE +.l3: + ADD HL, HL + JP NC, .l4 + ADD HL, DE +.l4: + ADD HL, HL + JP NC, .l5 + ADD HL, DE +.l5: + ADD HL, HL + JP NC, .l6 + ADD HL, DE +.l6: + ADD HL, HL + JP NC, .l7 + ADD HL, DE +.l7: + ADD HL, HL + JP NC, .l8 + ADD HL, DE +.l8: + LD E, H + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_4px_bc: + ; draw pixel(H+B, L+C) if in screen + LD A, H + ADD A, B + JP C, .l1 + LD D, A + LD A, L + ADD A, C + LD E, A + CALL dc_put_pixel +.l1: + ; draw pixel(H+B, L-C) if in screen + LD A, H + ADD A, B + JP C, .l2 + LD D, A + LD A, L + SUB C + LD E, A + CALL dc_put_pixel +.l2: + ; draw pixel(H-B, L-C) if in screen + LD A, H + SUB B + JP C, .l3 + LD D, A + LD A, L + SUB C + LD E, A + CALL dc_put_pixel +.l3: + ; draw pixel(H-B, L+C) if in screen + LD A, H + SUB B + RET C + LD D, A + LD A, L + ADD A, C + LD E, A + CALL dc_put_pixel ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_4px_cb: + ; draw pixel(H+C, L+B) if in screen + LD A, H + ADD A, C + JP C, .l1 + LD D, A + LD A, L + ADD A, B + LD E, A + CALL dc_put_pixel +.l1: + ; draw pixel(H+C, L-B) if in screen + LD A, H + ADD A, C + JP C, .l2 + LD D, A + LD A, L + SUB B + LD E, A + CALL dc_put_pixel +.l2: + ; draw pixel(H-C, L-B) if in screen + LD A, H + SUB C + JP C, .l3 + LD D, A + LD A, L + SUB B + LD E, A + CALL dc_put_pixel +.l3: + ; draw pixel(H-C, L+B) if in screen + LD A, H + SUB C + RET C + LD D, A + LD A, L + ADD A, B + LD E, A + CALL dc_put_pixel ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Draw pixel on screen +; Inp: DE - X, Y +; --------------------------------------------------- +dc_put_pixel: + RET C ; return if CF set (out of screen) + PUSH HL + PUSH BC + CALL calc_px_addr + ; calculate B = pixel mask + LD A, 10000000b +.roll: + RLCA ; [07654321] <- [76547210], [7] -> CF + DEC B + JP P, .roll + CPL + LD B, A + ; DE = foreground color low and hi bytes + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Turn on Video RAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; Load VRAM[HL] byte (low byte), mask and set + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; Load VRAM[HL+1] byte (low byte), mask and set + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; Turn off Video RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + POP BC + POP HL + RET + + ; Full charset, Common + RU letters (160*7=1120b) + INCLUDE "font-6x7.inc" + +; --------------------------------------------------- +; Read hex value from serial interface +; Out: A - value +; --------------------------------------------------- +read_hex_serial: + PUSH BC + CALL m_serial_in + CALL hex_nibble + RLCA + RLCA + RLCA + RLCA + LD C, A + CALL m_serial_in + CALL hex_nibble + OR C + LD C, A + ADD A, D + LD D, A + LD A, C + POP BC + RET + +; --------------------------------------------------- +; Convert digit 0..F to character '0'..'F' +; Inp: A - digit +; Out: A - character +; --------------------------------------------------- +hex_to_char: + AND 0xf + ADD A, 0x90 + DAA + ADC A, 0x40 + DAA + LD C, A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +out_reg_value: + INC HL ; second value in register t + LD E, (HL) + LD D, HIGH M_VARS.stor_de ; DE -> 0xBFxx - var reg sto + INC HL + LD B, (HL) + INC HL + LD A, (DE) ; Load register value + CALL out_hex_byte + DEC B + RET M ; ret if single register + ; print word register + DEC DE + LD A, (DE) + JP out_hex_byte + +get_address: + CALL s_get_hex_addr + EX (SP), HL + PUSH HL + DEC C + JP NC, ga_word + JP NZ, reset_m_stack + RET +ga_word: + JP NZ, get_address + JP reset_m_stack + + +; --------------------------------------------------- +; Next HL address until DE +; Inp: HL -start address +; DE - end address +; Out: HL = HL + 1 +; CF set if no more +; --------------------------------------------------- +next_hl_de: + INC HL + LD A, H + OR L + SCF + RET Z ; return if HL=0 + LD A, E + SUB L + LD A, D + SBC A, H + RET + +; --------------------------------------------------- +; Out hex word to screen +; Inp: HL - word to display +; --------------------------------------------------- +out_hex_word: + LD A, H + CALL out_hex_byte + LD A, L + +; --------------------------------------------------- +; Out hex byte to screen +; Inp: A - byte to display +; --------------------------------------------------- +out_hex_byte: + PUSH AF + RRCA + RRCA + RRCA + RRCA + CALL out_hex_nibble + POP AF + +; --------------------------------------------------- +; +; --------------------------------------------------- +out_hex_nibble: + CALL hex_to_char + JP get_key_out + +; --------------------------------------------------- +; +; --------------------------------------------------- +s_get_hex_addr: + CALL get_key_with_check + JP Z, reset_m_stack + +; --------------------------------------------------- +; Out: HL - address +; --------------------------------------------------- +hex_keys_to_addr: + LD HL, 0x0 +cvt_next_hex: + LD B, A + CALL hex_nibble + JP C, non_hex_symb + ; HL << 4 + ADD HL, HL ; HL*2 + ADD HL, HL ; HL*4 + ADD HL, HL ; HL*8 + ADD HL, HL ; HL*16 + OR L + LD L, A + CALL handle_key_pressed + JP cvt_next_hex +non_hex_symb: + LD A, B + CALL check_sep_key + JP NZ, reset_m_stack ; jump if no separator key + RET + +hex_nibble: + SUB '0' + RET C + ADD A, 233 + RET C + ADD A, 6 + JP P, .is_alpha + ADD A, 7 + RET C +.is_alpha + ADD A, 10 + OR A + RET + +; --------------------------------------------------- +; Read key from keyboard with check for separator cha +; Out: A - key pressed, converted to Upper Case +; ZF set if sep or CR +; CF set if CR +; --------------------------------------------------- +get_key_with_check: + CALL handle_key_pressed + + +; --------------------------------------------------- +; Inp: A - key +; Out: ZF set - if ', ' or or +; CF set - if +; --------------------------------------------------- +check_sep_key: + CP ASCII_SP + RET Z + CP ',' + RET Z + CP ASCII_CR + SCF + RET Z + CCF + RET + +; --------------------------------------------------- +; Read key, reset stack if ESC. Print symbol to console +; Out: A - key code +; --------------------------------------------------- +handle_key_pressed: + PUSH BC + CALL m_con_in + CALL hex_to_upper + CP ASCII_ESC + JP Z, reset_m_stack + LD C, A + CALL m_con_out + LD A, C + POP BC + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +hex_to_upper: + CP 'a' + RET M + CP 155 + RET P + AND 11011111b + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_rst1_handler: + DI + LD (M_VARS.store_hl), HL + LD HL, 0x2 + ADD HL, SP + LD (M_VARS.stack_0), HL + POP HL + LD SP, M_VARS.stack_0 + PUSH AF + LD A, 0x0 + PUSH AF + LD A, 0x0 + NOP + NOP + PUSH BC + PUSH DE + LD A, 0x0 + NOP + NOP + LD (M_VARS.store_pc), HL + CALL get_cmd_letter + INC HL + CALL out_hex_word + JP m_cold_start + + +; --------------------------------------------------- +; G[addr] Run program from addr +; --------------------------------------------------- +cmd_G: + CALL get_key_with_check + JP Z, .sep + CALL hex_keys_to_addr + LD (M_VARS.store_pc), HL +.sep: + JP NC, reset_m_stack ; reset if unknown key + CALL get_a_ref_sp + LD A, JP_OPCODE ; JP + LD (M_VARS.start_jp), A + LD SP, M_VARS.stor_e + ; restore registers and stack + POP DE + POP BC + POP AF + NOP + NOP + POP AF + POP HL + LD SP, HL + ; restore HL and start code at specified address + LD HL, (M_VARS.store_hl) + JP M_VARS.start_jp + +; --------------------------------------------------- +; W - Write RAM to tape +; --------------------------------------------------- +cmd_W: + CALL get_key_with_check + JP NC, reset_m_stack + CALL get_a_ref_sp + +; --------------------------------------------------- +; Wtite RAM-Disk 64K to TAPE +; --------------------------------------------------- +m_tape_write_ram: + LD HL, M_VARS.buffer + LD C, 128 +.cl_stack: + LD (HL), 0x0 + INC HL + DEC C + JP NZ, .cl_stack + LD HL, M_VARS.buffer + LD DE, 0xffff + ; write empty block + ; DE - block ID + ; HL -> block + CALL m_tape_write + CALL twr2_delay + LD DE, 0x0 + CALL m_tape_write + CALL twr2_delay + LD BC, 512 + LD DE, 0x0 +.nxt_blk: + PUSH BC + LD HL, M_VARS.buffer + CALL m_ramdisk_read + INC DE + CALL m_tape_write + CALL twr2_delay + POP BC + DEC BC + LD A, B + OR C + JP NZ, .nxt_blk + RET + +; --------------------------------------------------- +; Pause between blocks on tape +; --------------------------------------------------- +twr2_delay: + LD BC, 250 +.delay: + DEC BC + LD A, B + OR C + JP NZ, .delay + RET + +; --------------------------------------------------- +; R - Read from tape to RAM +; --------------------------------------------------- +cmd_R: + CALL get_key_with_check + JP NC, reset_m_stack + CALL get_a_ref_sp + +; --------------------------------------------------- +; Read RAM-Disk 64K from TAPE +; --------------------------------------------------- +m_tape_read_ram: + LD A, 100 + CALL m_tape_wait + OR A + JP NZ, .end + LD E, 6 + +.srch_first: + DEC E + JP Z, .not_found + ; read block + LD HL, M_VARS.buffer + CALL m_tape_read + CP 4 + JP Z, .end + OR A + JP NZ, .srch_first + LD A, B + OR C + JP NZ, .srch_first + + LD BC, 512 + LD DE, 0x0 + +.rd_next: + PUSH BC + ; Read block from tape + CALL m_tape_read + OR A + JP NZ, .rd_error + DEC BC + LD A, B + CP D + JP NZ, .inv_id + LD A, C + CP E + JP NZ, .inv_id + ; Ok, write block to RAM disk + CALL m_ramdisk_write + INC DE + POP BC + DEC BC + LD A, B + OR C + JP NZ, .rd_next + RET +.not_found: + LD HL, msg_no_start_rec + CALL me_out_strz ; TODO: replace call+ret to jp + RET +.rd_error: + CP 2 + JP Z, .err_ubi + CP 4 + JP Z, .err_ibu + LD HL, msg_checksum + CALL me_out_strz + CALL out_hexw + POP BC + RET + + ; Illegal sequence of blocks +.inv_id: + LD HL, msg_sequence + CALL me_out_strz + INC BC + CALL out_hexw + POP BC + RET + +.err_ubi: + LD HL, msg_ibg + CALL me_out_strz + POP BC + RET + + ; Interrupted by user +.err_ibu: + POP BC + +.end: + LD HL, msg_break + CALL me_out_strz ; TODO: replace call+ret to jp + RET + +; -------------------------------------------------- +; Output hex word +; Inp: BC - word to output +; -------------------------------------------------- +out_hexw: + PUSH BC + LD A, B + CALL out_hex_byte + POP BC + LD A, C + CALL out_hex_byte ; TODO: replace call+ret to jp + RET + +msg_no_start_rec: + DB "NO START RECORD", 0 +msg_checksum: + DB "CHECKSUM ", 0 +msg_sequence: + DB "SEQUENCE ", 0 +msg_ibg: + DB "IBG", 0 +msg_break: + DB "BREAK", 0 + +; --------------------------------------------------- +; Out ASCIIZ message +; Inp: HL -> zero ended string +; --------------------------------------------------- +me_out_strz: + LD A, (HL) + OR A + RET Z + PUSH BC + LD C, A + CALL m_con_out + INC HL + POP BC + JP me_out_strz + + + +; --------------------------------------------------- +; Read from RAM-disk to RAM +; Inp: DE - source sector +; HL -> destination buffer +; --------------------------------------------------- +m_ramdisk_read: + PUSH HL + PUSH DE + LD A, D + ; Build value to access ext RAM (A17, A16, 32k bits) + AND 00000001b ; Low 32K + OR 0x2 ; Set A16 address line + OR 0x0 ; TODO: nothing, remove + LD B, A ; B - value to turn on access to Ext RAM + ; Calculate DE = address from sector number + XOR A + LD A, E ; E - low address + RRA ; [CF] -> [7:0] -> [CF] + LD D, A ; D = E/2 + LD A, 0x0 + RRA ; [CF] -> E + LD E, A +.read: + ; Access to ExtRAM + LD A, B + OUT (SYS_DD17PB), A + ; Get Byte + LD A, (DE) + LD C, A + ; Access to RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + ; Set Byte + LD (HL), C + ; HL++, DE++ + INC HL + INC DE + LD A, E + ADD A, A + JP NZ, .read ; jump if has more bytes + + ; Access to RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + + POP DE + POP HL + RET + +; --------------------------------------------------- +; Write sector to RAM disk +; Inp: HL -> source buffer +; DE - destination sector +; --------------------------------------------------- +m_ramdisk_write: + PUSH HL + PUSH DE + LD A, D + AND 0x1 + OR 0x2 ; build value to access ext RAM (A16, 32k bits) + OR 0x0 ; TODO: remove unused + LD B, A + XOR A + LD A, E + RRA + LD D, A + LD A, 0x0 + RRA + LD E, A +.wr_byte: + LD A, 0x0 + OUT (SYS_DD17PB), A + LD C, (HL) + LD A, B + OUT (SYS_DD17PB), A + LD A, C + LD (DE), A + INC HL + INC DE + LD A, E + ADD A, A + JP NZ, .wr_byte + LD A, 0x0 + OUT (SYS_DD17PB), A + POP DE + POP HL + RET + +; -------------------------------------------------- +; Write block to Tape +; Inp: DE - block ID, +; HL -> block of data. +; -------------------------------------------------- +m_tape_write: + PUSH HL + PUSH DE + PUSH DE + LD BC, 2550 + LD A, PIC_POLL_MODE ; pool mode + OUT (PIC_DD75RS), A + LD A,TMR0_SQWAVE ; tmr0, load lsb+msb, sq wave, bin + OUT (TMR_DD70CTR), A + LD A, C + OUT (TMR_DD70C1), A + LD A, B + OUT (TMR_DD70C1), A + ; Write Hi+Lo, Hi+Lo + LD DE, 4 ; repeat next 4 times +.l1: + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; check rst4 from timer#0 + JP NZ, .l1 + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH ; tape level hi + JP NZ, .set_lvl + LD A, TL_LOW ; tape level low +.set_lvl: + OUT (DD67PC), A ; set tape level + LD A, TMR0_SQWAVE ; tmr0, load lsb+msb, swq, bin + ; timer on + OUT (TMR_DD70CTR), A + LD A, C + OUT (TMR_DD70C1), A + LD A, B + OUT (TMR_DD70C1), A + DEC E + JP NZ, .l1 + +.l2: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .l2 + + ; Write 00 at start + LD A, 0x0 + CALL m_tape_wr_byte + ; Write 0xF5 marker + LD A, 0xf5 + CALL m_tape_wr_byte + LD E, 0x0 ; checksum=0 + ; Write block ID + POP BC + LD A, C + CALL m_tape_wr_byte + LD A, B + CALL m_tape_wr_byte + ; Write 128 data bytes + LD B, 128 +.next_byte: + LD A, (HL) + CALL m_tape_wr_byte + INC HL + DEC B + JP NZ, .next_byte + ; Write checksum + LD A, E + CALL m_tape_wr_byte + ; Write final zero byte + LD A, 0x0 + CALL m_tape_wr_byte +.wait_end: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .wait_end + LD A, TL_MID ; tape level middle + OUT (DD67PC), A + POP DE + POP HL + RET + + +; ------------------------------------------------------ +; Write byte to tape +; Inp: A - byte top write +; D - current level +; E - current checksum +; ------------------------------------------------------ +m_tape_wr_byte: + PUSH BC + ; calc checksum + LD B, A + LD A, E + SUB B + LD E, A + LD C, 8 ; 8 bit in byte +.get_bit: + LD A, B + RRA + LD B, A + JP C, .bit_hi +.wait_t: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .wait_t + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; program for 360 cycles + LD A, 0x68 + OUT (TMR_DD70C1), A + LD A, 0x1 + OUT (TMR_DD70C1), A + ; change amplitude + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH + JP NZ, .out_bit + LD A, TL_LOW +.out_bit: + OUT (DD67PC), A + DEC C + JP NZ,.get_bit + POP BC + RET +.bit_hi: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .bit_hi + ; program for 660 cycles + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + LD A, 0x94 + OUT (TMR_DD70C1), A + LD A, 0x2 + OUT (TMR_DD70C1), A + ; change amplitude + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH + JP NZ, .out_bit_hi + LD A, TL_LOW +.out_bit_hi: + OUT (DD67PC), A + DEC C + JP NZ, .get_bit + POP BC + RET + +; ------------------------------------------------------ +; Load block from Tape +; Inp: HL -> buffer to receive bytes from Tape +; Out: A = 0 - ok, +; 1 - CRC error, +; 2 - unexpected block Id +; 4 - key pressed +; ------------------------------------------------------ +m_tape_read: + PUSH HL + PUSH DE + LD A, PIC_POLL_MODE ; pool mode + OUT (PIC_DD75RS), A + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A ; tmr0, load lsb+msb, sq wave + LD A, 0x0 + ; tmr0 load 0x0000 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + LD C, 3 +.wait_3_changes: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + LD A, B + ADD A, 4 + JP P, .wait_3_changes + DEC C + JP NZ, .wait_3_changes +.wait_4th_change: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + LD A, B + ADD A, 4 + JP M, .wait_4th_change + LD C, 0x0 +.wait_f5_marker: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + DEC A + RRA + LD A, C + RRA + LD C, A + CP 0xf5 + JP NZ, .wait_f5_marker + LD E, 0x0 ; checksum = 0 + ; Read blk ID + CALL m_tape_read_byte + JP NC, .err_read_id + LD C, D + CALL m_tape_read_byte + JP NC, .err_read_id + LD B, D + PUSH BC + ; Read block, 128 bytes + LD C, 128 +.read_next_b: + CALL m_tape_read_byte + JP NC, .err_read_blk + LD (HL), D + INC HL + DEC C + JP NZ, .read_next_b + + ; Read checksum + CALL m_tape_read_byte + JP NC, .err_read_blk + LD A, E + OR A + JP Z, .checksum_ok + LD A, 0x1 ; bad checksum +.checksum_ok: + POP BC +.return: + POP DE + POP HL + RET + +.err_read_blk: + POP BC + LD BC, 0x0 +.err_read_id: + LD A, 0x2 ; read error + JP .return +.key_pressed: + CALL m_con_in + LD C, A ; store key code in C + LD B, 0x0 + LD A, 0x4 + JP .return + +; ------------------------------------------------------ +; Read byte from Tape +; Out: D - byte +; CF is set if ok, cleared if error +; ------------------------------------------------------ +m_tape_read_byte: + PUSH BC + LD C, 8 +.next_bit: + CALL m_read_tape_bit + ; push bit from lo to hi in D + RRA + LD A, D + RRA + LD D, A + LD A, 4 + ADD A, B + JP NC, .ret_err + DEC C + JP NZ, .next_bit + ; calc checksum + LD A, D + ADD A, E + LD E, A + SCF +.ret_err: + POP BC + RET + +; ------------------------------------------------------ +; Read bit from tape +; Out: A - bit from tape +; B - time from last bit +; ------------------------------------------------------ +m_read_tape_bit: + IN A, (KBD_DD78PB) ; Read Tape bit 5 (data) + AND TAPE_P + LD B, A +.wait_change: + IN A, (KBD_DD78PB) + AND TAPE_P + CP B + JP Z, .wait_change + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; [360...480...660] 0x220=544d + IN A, (TMR_DD70C1) ; get tmer#0 lsb + ADD A, 0x20 + IN A, (TMR_DD70C1) ; get tmer#0 msb + LD B, A + ADC A, 0x2 + ; reset timer to 0 + LD A, 0x0 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + ; For 0 - 65535-360+544 -> overflow P/V=1 + ; For 1 - 65535-660+544 -> no overflow P/V=0 + RET P + INC A + RET + +; ------------------------------------------------------ +; Read bit from tape with keyboard interruption +; Out: A - bit from tape +; B - time from last bit +; ------------------------------------------------------ +read_tape_bit_kbd: + IN A, (KBD_DD78PB) + AND TAPE_P + LD B, A ; save tape bit state + ; wait change with keyboard check +.wait_change: + IN A, (PIC_DD75RS) + AND KBD_IRQ + JP NZ, .key_pressed + IN A, (KBD_DD78PB) + AND TAPE_P + CP B + JP Z, .wait_change + ; measure time + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; read lsb+msb + IN A, (TMR_DD70C1) + ADD A, 0x20 + IN A, (TMR_DD70C1) + LD B, A + ADC A, 0x2 + ; reset timer#0 + LD A, 0x0 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + ; flag P/V is set for 0 + RET P + INC A + RET +.key_pressed: + LD A, 0xff + RET + +; ------------------------------------------------------ +; Wait tape block +; Inp: A - periods to wait +; Out: A=4 - interrupded by keyboard, C=key +; ------------------------------------------------------ +m_tape_wait: + OR A + RET Z + PUSH DE + LD B, A +.wait_t4: + LD C,B + IN A, (KBD_DD78PB) + AND TAPE_P ; Get TAPE4 (Wait det) and save + LD E, A ; store T4 state to E +.wait_next_2ms: + LD A,TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; load 3072 = 2ms + XOR A + OUT (TMR_DD70C1), A + LD A, 0xc + OUT (TMR_DD70C1), A +.wait_tmr_key: + IN A, (PIC_DD75RS) + AND KBD_IRQ ; RST1 flag (keyboard) + JP NZ, .key_pressed + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; RST4 flag (timer out) + JP Z, .wait_no_rst4 + IN A, (KBD_DD78PB) + AND TAPE_P ; TAPE4 not changed? + CP E + JP NZ, .wait_t4 ; continue wait + JP .wait_tmr_key +.wait_no_rst4: + DEC C + JP NZ, .wait_next_2ms + XOR A + POP DE + RET + +.key_pressed: + CALL m_con_in + LD C, A ; C = key pressed + LD A, 0x4 ; a=4 interrupted by key + POP DE + RET + +; ------------------------------------------------------ +; Check block marker from Tape +; Out: A=0 - not detected, 0xff - detected +; ------------------------------------------------------ +m_tape_blk_detect: + IN A, (KBD_DD78PB) + AND TAPE_D ; TAPE5 - Pause detector + LD A, 0x0 + RET Z + CPL + RET + +; ====================================================== +; FDC DRIVER +; ====================================================== +fdc_unload_head: + LD A,0x0 + OUT (FDC_DATA),A + LD A,0x3 + OUT (FDC_CMD),A + NOP + NOP +fuh.wait_no_busy: + IN A,(FDC_CMD) + AND 0x5 ; TR0. BYSY + CP 0x4 ; + JP Z,fuh.tr0_ok + IN A,(FLOPPY) + RLCA ; MOT_ST -> CF + JP NC,fuh.wait_no_busy + LD A,0x20 + RET +fuh.tr0_ok: + LD A,0x1 + LD (M_VARS.ul_var1),A + XOR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_select_drive: + CALL delay_1.4mS + CP 0x1 + JP Z, .sel_a + LD A, 0x2 + JP .sel_b +.sel_a: + LD A, 0x5 +.sel_b: + LD B, A + IN A, (FLOPPY) + AND 0x40 + RRA + OR B + OUT (FLOPPY), A + LD B, A + LD A, D + CP 0x28 + JP C, .l3 + SUB 0x28 + LD D, A + LD A, C + OR 0x8 + LD C, A + LD A, B + AND 0x20 + OR A + RET NZ + LD A, B + OR 0x20 + OUT (FLOPPY), A + CALL delay_136uS + RET +.l3: + LD A, B + AND 0x20 + OR A + RET Z + LD A, B + AND 0x7 + OUT (FLOPPY), A + CALL delay_136uS + RET + + +; --------------------------------------------------- +; Delay for 136uS +; --------------------------------------------------- +delay_136uS: + LD B, 16 ; 7 + +; --------------------------------------------------- +; Delay for B*8uS +; --------------------------------------------------- +delay_b: + DEC B ; 4 + JP NZ, delay_b ; 10 + RET ; 10 + +; --------------------------------------------------- +; Delay for 1.4mS +; --------------------------------------------------- +delay_1.4mS: + LD B, 175 ; 7 + JP delay_b ; 10 + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_read_floppy: + CALL m_select_drive + CALL m_start_seek_track + JP C, fdc_ret + CALL m_fdc_read_c_bytes + JP C, fdc_ret + XOR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_write_floppy: + CALL m_select_drive + CALL m_start_seek_track + JP C, fdc_ret + CALL m_fdc_write_bytes + JP C, fdc_ret + XOR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_start_seek_track: + CALL m_start_floppy + RET C + CALL m_fdc_seek_trk + RET C + RET ; TODO: remove + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_start_floppy: + IN A, (FLOPPY) + RLCA + JP C, .wait_motor_st + IN A, (FDC_CMD) + AND 0x80 + RET Z +.wait_motor_st: + PUSH BC + LD BC, 64000 + CALL fdc_init +.wait_rdy1: + IN A, (FDC_CMD) + AND 0x80 + JP Z, .long_delay + IN A, (FLOPPY) + RLCA + JP NC, .wait_rdy1 + LD A, 0x20 + JP .mot_st_exit +.long_delay: + DEC C + JP NZ, .long_delay + DEC B + JP NZ, .long_delay + XOR A +.mot_st_exit: + POP BC + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +fdc_init: + IN A, (FLOPPY) + AND 01001110b ; Get SSEL, DRSEL, MOT1, MOT0 + RRA + OUT (FLOPPY), A + OR 0x08 ; Set INIT bit + OUT (FLOPPY), A + RET + +; --------------------------------------------------- +; Seek track on floppy +; Inp: DE - track/sector +; --------------------------------------------------- +m_fdc_seek_trk: + LD A, (M_VARS.ul_var1) + AND 0x1 + CALL Z, fdc_unload_head + LD A, D + OUT (FDC_DATA), A + LD A, 0x1f + OUT (FDC_CMD), A + NOP + NOP + IN A, (FDC_WAIT) + IN A, (FDC_CMD) + AND ASCII_EM + CP 0x0 + JP NZ, .l1 + JP .l2 +.l1: + LD A, D + OUT (FDC_DATA), A + LD A, 0x2f + OUT (FDC_CMD), A + NOP + NOP + IN A, (FDC_WAIT) + IN A, (FDC_CMD) + AND ASCII_EM + CP 0x0 + JP Z, .l2 + SCF + LD A, 0x40 +.l2: + PUSH AF + LD A, E + OUT (FDC_SECT), A + POP AF + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_fdc_write_bytes: + LD A, C + OUT (FDC_CMD), A +.w_next: + IN A, (FDC_WAIT) + RRCA + LD A, (HL) + OUT (FDC_DATA), A + INC HL + JP C, .w_next + CALL fdc_check_status ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_fdc_read_c_bytes: + LD A, C + OUT (FDC_CMD), A + JP .l2 +.l1: + LD (HL), A + INC HL +.l2: + IN A, (FDC_WAIT) + RRCA + IN A, (FDC_DATA) + JP C, .l1 + CALL fdc_check_status ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Check fdc status for errors +; Out: CF set if errors +; --------------------------------------------------- +fdc_check_status: + IN A,(FDC_CMD) + AND 11011111b + CP 0x0 + JP Z,fdc_ret + IN A,(FDC_CMD) + CP 0x80 + LD C,0x80 + JP Z,fcs_error + CP 0x40 + LD C,0x3 + JP Z,fcs_error + CP 0x10 + LD C,0x4 + JP Z,fcs_error + CP 0x8 + LD C,0x9 + JP Z,fcs_error + LD C,0x10 +fcs_error: + SCF + LD A,C +fdc_ret: + RET + + DB "\r\n DRIVE IS NOT READY \r\n", 0, "I" + +; ------------------------------------------------------ + +LAST EQU $ +CODE_SIZE EQU LAST-0xe000 +FILL_SIZE EQU ROM_CHIP_SIZE-CODE_SIZE + + + ASSERT m_start = 0xe036 + ASSERT conf_uart = 0xe08c + ASSERT conf_pic = 0xe09f + ASSERT jump_bios = 0xe0d6 + ASSERT m_out_strz = 0xe0e7 + ASSERT m_cold_start = 0xe10c + ASSERT registers_tab = 0xe27e + ASSERT m_char_print = 0xe2e8 + ASSERT m_con_out = 0xe307 + ASSERT m_con_out_int = 0xe311 + ASSERT get_esc_param = 0xe32b + ASSERT esc_params_tab = 0xe3ae + ASSERT esc_set_beep = 0xe3dd + ASSERT esc_print_screen = 0xe3fb + ASSERT m_print_hor_line = 0xe424 + ASSERT m_get_7vpix = 0xe49e + ASSERT esc_set_palette = 0xe4e8 + ASSERT m_get_glyph = 0xe50a + ASSERT m_print_no_esc = 0xe533 + ASSERT calc_addr_40 = 0xe6b2 + ASSERT mp_mode_64 = 0xe72e + ASSERT scroll_up = 0xe777 + ASSERT mp_mode_80 = 0xe7c2 + ASSERT m80_rt = 0xe85d + ASSERT calc_addr_80 = 0xe8a0 + ASSERT m_clear_screen = 0xe900 + ASSERT m_cursor_home = 0xe933 + ASSERT m_draw_cursor = 0xe961 + ASSERT m_handle_esc_code = 0xeb04 + ASSERT handle_cc_common = 0xeb4c + ASSERT handle_cc_mono = 0xeb87 + ASSERT handle_cc_80x25 = 0xebce + ASSERT m_beep = 0xebf5 + ASSERT esc_set_cursor = 0xec2b + ASSERT esc_set_vmode = 0xec8b + ASSERT esc_set_color = 0xecbc + ASSERT m_print_at_xy = 0xecd0 + ASSERT calc_px_addr = 0xed4b + ASSERT esc_draw_fill_rect = 0xed5e + ASSERT esc_draw_line = 0xedf7 + ASSERT esc_draw_dot = 0xef3e + ASSERT esc_draw_circle = 0xef62 + ASSERT dc_put_pixel = 0xf0a8 + ASSERT get_key_with_check = 0xf5ce + ASSERT m_tape_write_ram = 0xf654 + ASSERT m_tape_read_ram = 0xf6a4 + ASSERT m_ramdisk_read = 0xf76a + ASSERT m_ramdisk_write = 0xf794 + ASSERT m_tape_write = 0xf7be + ASSERT m_tape_wr_byte = 0xf835 + ASSERT m_tape_read = 0xf88e + ASSERT m_read_tape_bit = 0xf92f + ASSERT m_tape_wait = 0xf97f + ASSERT m_select_drive = 0xf9e8 + + ASSERT m_read_floppy = 0xfa36 + ASSERT m_write_floppy = 0xfa47 + ASSERT m_start_floppy = 0xfa61 + ASSERT fdc_init = 0xfa90 + ASSERT m_fdc_seek_trk = 0xfa9c + ASSERT m_fdc_write_bytes = 0xfad8 + ASSERT m_fdc_read_c_bytes = 0xfae9 + ASSERT fdc_check_status = 0xfafd + + + ;DISPLAY "m_handle_esc_code: ", /H, m_handle_esc_code + +FILLER + DS FILL_SIZE, 0xFF + DISPLAY "Free size is: ", /D, FILL_SIZE, " bytes." + + ENDMODULE + + OUTEND + + OUTPUT m_vars.bin + ; put in separate waste file + INCLUDE "m_vars.inc" + OUTEND diff --git a/MON_r6_291f2b76/ram.inc b/MON_r6_291f2b76/ram.inc new file mode 100644 index 0000000..8c6c08e --- /dev/null +++ b/MON_r6_291f2b76/ram.inc @@ -0,0 +1,49 @@ +; ======================================================= +; Ocean-240.2 +; +; RAM area at address: 0x0000 - 0x0100, used by CP/M and +; HW-Monitor +; By Romych 2026-02-03 +; ======================================================= + + IFNDEF _RAM + DEFINE _RAM + + MODULE RAM + +@warm_boot EQU 0x0000 ; Jump warm_boot (Restart) +@warm_boot_addr EQU 0x0001 ; address of warm boot entry point +@iobyte EQU 0x0003 ; Input/Output mapping +@cur_user_drv EQU 0x0004 ; [7:4] - curent user, [3:0] - current drive +@jp_bdos_enter EQU 0x0005 ; Jump bdos (CALL 5 to make CP/M requests) +@bdos_ent_addr EQU 0x0006 ; addres of BDOS entry point +@RST1 EQU 0x0008 +@RST1_handler_addr EQU 0x0009 +;RST2 EQU 0x0010 +;RST3 EQU 0x0018 +;RST4 EQU 0x0020 +;RST5 EQU 0x0028 +;RST6 EQU 0x0030 +;RST7 EQU 0x0038 +;reserve1 EQU 0x003b +@bios_var0 EQU 0x0040 ; 0xaa - bios init r8 +@bios_var1 EQU 0x0041 ; 0xaa - bios init r8 +@bios_var2 EQU 0x0042 ; 0x00 - bios init r8 +@bios_var3 EQU 0x0043 ; 0xff - bios init r8 +@interleave_0 EQU 0x0044 +;reserve2 EQU 0x0050 +@fcb1 EQU 0x005c ; Default FCB, 16 bytes +@fcb2 EQU 0x006c +;NMI_ISR EQU 0x0066 + +@dma_buffer EQU 0x0080 ; Default "DMA" 128 bytes buffer +@p_cmd_line_len EQU 0x0080 ; command line character count +@p_cmd_line EQU 0x0081 ; command line buffer +@fcb_ra_record_num EQU 0x00a1 +@bios_stack EQU 0x0100 +@tpa_start EQU 0x0100 ; start of program +@video_ram EQU 0x4000 + + ENDMODULE + + ENDIF \ No newline at end of file diff --git a/MON_r7_58d6d2a8/.gitignore b/MON_r7_58d6d2a8/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/MON_r7_58d6d2a8/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld - diff --git a/MON_r8_3edeb015/.gitignore b/MON_r8_3edeb015/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/MON_r8_3edeb015/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld - diff --git a/MON_r8_9c6c6546/.vscode/extensions.json b/MON_r8_9c6c6546/.vscode/extensions.json new file mode 100644 index 0000000..1fdc4e8 --- /dev/null +++ b/MON_r8_9c6c6546/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "maziac.asm-code-lens", + "maziac.dezog", + "maziac.hex-hover-converter", + "maziac.z80-instruction-set", + "maziac.sna-fileviewer" + ] +} diff --git a/MON_r8_9c6c6546/.vscode/tasks.json b/MON_r8_9c6c6546/.vscode/tasks.json new file mode 100644 index 0000000..9c09341 --- /dev/null +++ b/MON_r8_9c6c6546/.vscode/tasks.json @@ -0,0 +1,34 @@ +{ + "version": "2.0.0", + "tasks": [ + + { + "label": "make MONITOR (sjasmplus)", + "type": "shell", + "command": "sjasmplus", + "args": [ + "--sld=monitor.sld", + "--sym=monitor.labels", + "--raw=monitor.obj", + "--fullpath", + "monitor.asm" + ], + "problemMatcher": { + "owner": "sjasmplus", + "fileLocation": "autoDetect", + "pattern": { + "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "severity": 3, + "message": 4 + } + }, + "group": { + "kind": "build", + "isDefault": true + } + } + + ] +} \ No newline at end of file diff --git a/MON_r8_9c6c6546/BIN/MON_r8_9c6c6546.BIN b/MON_r8_9c6c6546/BIN/MON_r8_9c6c6546.BIN new file mode 100644 index 0000000000000000000000000000000000000000..c11004f536a1f42e783533665bb0401816f302e4 GIT binary patch literal 8192 zcmdTp3s)Q0nIjannIFk;+UwjX?``MIIKQ0U{ofKqL_`+V8u< zkEY!pup`aA-~I0QzTbV!40q2}ZcCEO4{=*V+=C&mEW|a1xPu|CV~zXaD%ZTqJ+{i7 zOme%D+_81;`|I2enQNB0*i|k!#yMl$&!b%PEcZ}^E1KgrEpm4*FVX!0E-*=dFVIZ) z1wynU;MGtTYEQ3!@8i}#vR}PQQvolX8DJacn1P0?OhcGym}2T1CK)=TVVa?vfkzdX zXqaa#l&W%uvDg)rA29S^0zajz;XV;~kS+*(aUk$TIzP}q5I9vII7L?k`spmV`vdzZ zY9O%hpWbA|7bJbA_+ZFJjmexqjak;NieR)Mbg0WS1b8dBkdt-a=kGgw;I4{8Er%;^ zYdLage@+&4V!WS{lr%L|&yW99QVM0E@v~ANFXo3l!q(8ZouU$`2eibHKp`}Rx&mkU z@qS4w91L|)fvaHO1UA`L;t3xf^@)##yu%^h5MWB0Jju^Zvdy!`5>Nbes7uPtHxA_U zmj7XHv$`9dZG}|v*DY^_jurpuBfz<(+_qZJF6B@m^+c& zu>O$29~zwv1FqU*eh>dCB1BU0$%n-SQhSUzxHnF)dO8nkFA#M%Hr9+5fD<%rB0>E4T zYeGCRVNp?)3yg-+Q{wL@UVQWP#I^;-3K+fOZ`&%DJQqATVfh6z@jka)B0MwEA|8Z+ za87vngyj|N0OmUZcNg52-y$N0Bz)=p%97G!6a_^|X-kPM%=G(>ouj@UDbvwoHk&2$ zX}`UrOHw@Df%$g4s_H0anL0T;(QR(+F}HE=O!O2|=8^bB;STdia-w@>u(jJe%-hBo zX%A$bgLq9-tZ|aIzZwXUj*JG0;XB&~T03frYl?ehdvgDzO=3L4{>di6KG`F;1Hv$< zC^o#aT+DY#eR4&zcUr8NjHJir{FHd>R2>>rUF~{Ra89a)Q*eKCl6!8ls!B1KqABhN zlZri2T7z}&8m+=QBSkA4R+xxwg$aLc3*`}hJz3Ml{$euX{;AV8$^7iUomB`;rJ=Kk zdl7K}O(9fQU0odsS#1fXsUg9zFHB-6EH6l5ONg<${R(N1Q{Gzpk#)dXi*{<+ho;>A zEcv66fzUU@CU+(ZQKSX`K3wq00q%3k zcc%yVhPPy3`{X`hC5!{xk{(#4blsIS6BoP@R24dN!J#6 z17(l&`t2GDSNVITi0!6X^@v1f)c{2~G3`iDF%|R$7`82TjeP)P{;X7&!#*WpH}_Qu z6{rT&Qz>IQ0%P4PZ;eF55tvoTR$X1E&xCpPwxkv=!~L$rO-fZ&1~bJ;l3_3t%cug& zUdsJ4Oc1<(O>UebIjlr9g)o)siF_~#^VuGWMj)Y3heF%ue#r?|S*9bz>a-bmgBdX9 z`b;vrT^@~DI6mEE$Q%?Nfl3jDO4D1-9iL7!AD`w&)1Z-a_iDd7EfeeZbvTYwQk!>>!y({qG$v}H=pxrjlIJ(ab zmAV$R4zfe$v0XDa8p1bbxXu}H9Cjwl1Z+xU6}T*ec>mEwIW(!S`qABFE{|{imHEl($@ENJ_$rpDS;=1g@6Pg1uX3ogg!J zR?2|Y-!Mz^6c$SHRtcHhD=H_nxRP17wCaQkH;fFkgQk802NqXTJse%gOu(HOc7PUH zAxzA|J|N9n#u#^-UmKKWomTq8KS6y|yeD#UOxqc@eaLv&Z_IYVR-w-vF5`YY+XV(& zN9Jcc2RdqMY7Do2P^{Mu+paK8LTomSi3l43tS!Hvg`HqvHiFy0E6%DaT>4*eR^whk zny~&u6D9^p){r%aeQ}m=_>kcTpy2$WVNSYPT*e0=PM(eUKu*2G{nELYK&Jbp-@Qac zegcD1y(DizY;2aNHZJ$6Uz~d5N2lEG)Od=UPPr+qw&1}6t#(&mUmsnjrL<)7@WYKo?xLdc#_8$C@uKNz%I&76r`@McrBbI(xv8Q?=uBVk#v+Q! z+tJszBafoA*|MCirJmhiX~5f1x&K+bbK#0^TnMK&E;JKC#Nl;~265PT@#4;%ct5T^ z0T_1?H$DzFjdN=k*Rr$qxtX$G_WPxdjG{)gw(4PpQl-tSu=n@dEAq4|JZ_~glm%A` z7Lo5Zb#9zYBpMbH9#Y}B^^nziwEH>s$w*@h*cnpl6t_8!o_&9vIyXWB-?K5=-#8yc=tvz`bKU8Lt-rVXRA)kx3p+L|NVCYeajS;&uWEV?|xrnwy3+l=sj&cRl}K9JXnLWuP}HrJ zB4hbE^Dzjhyo4q;i4C*1zrwNNA_McF({`EZXb>2*u3?OULkrJDz_rTD4BelpjCSDy#>;MgHXIN$GtWOAaucO49{WzpCM{KrftIr z+Yn5wx_Pj@PIS%#v@OWk-eDYd;tSX!N;l7QZ_IzvBD4n7yaf)w#c;m4zn9x6r_z$Q z|BdABpOh>%EU-_{LtN;Thwr{HRN%^VjGURTs!Det7NK9wL%^`n^ZL+cSFU5^+gIdo)KD2}&RQUv zg>^!Ask)l)_6(U&VbuarC=@NAiI=LXcuX+&S@z&UmAm>Z+q!^j!XJ3jXd?|;@dqA} zv~r`)_yZrR{4)~?^?C&VLZy#MXURd5Chi5y5*Qp9l~(KsGIx`XA1*Y!gE<4UA}9W{ z1#=q!ruc6b>RZ8U9LaG8CI`#{?uEH+mzc^)W}C=-Ow5Die|O<}^1EL?OSb;Au=zv! zYZgiRzq9aU)e}`Y?CJuSAZDkh=~1iO`f%rkVCiC{a*XNuerNad9f^_J#rnpM$hI*i zA{0hXdW5$Y9Wk2vPD7CSfgJktv6Ip{$%kcE33iE*A{cObKm?2*gEbfix^$6YxgZdZt<3? zDn}0cwZ%|~zw?@=VbDax$54K7^^;NzQIH+}2iQ7pmB{8}cb)XG<OmFyz z;kW&jam%(rD?IyJ-S9vG#R_8$AF|$NwMIr!nm9&u4~M>PeOwfl@bL{!C0|~G^U1?; zIGPkM!Exn{IGmG~qWmN6@NCoqk5>*+5f4G&U|Dg-z{uPfzwHWBch~+0#LPqu4!3Vq zkwralSQmNH`h?X>s}hkk7;9ob9gDz9rqk8vYGB25JZ>$$z#fdf4)*|<=mlm&7F8U9 zr6uAMt#L2t^edr9&Kly{Vu0RdvxbSfUcbuG{&}J@gnGaSD=M#v_`(p#;gk8s-h87g z-{>W-hGIM{RF3ki5py6OasSq7b)R#B^-t6e8@)Mfb=+&Us@bYIUs~c<=F7S(v@+l5`_iLU zd^%0w<7wmRez`yR&G?wz0Rxgiv^(Dl=30#q;WjV)8fEa!L<~0Esfcm967#XqN45O_u3AZ*5dR2bq#4N)$H@2 z;ml1M(B4w8a1Z;(B~4#7`p5dLtN=V>)45B{W5DS-e_)D&fgABAUYz!1@t3aUbrNw3N>7|aF(2*khM0OxIk zK2v8f7<8Ftg(6p>FsCa8^lb(u&;#^fD6tcsIJ8=w#-LMYsCCE;m)THiG69LfU^EpI z>yRGBLnqj2fM8(@7|H>WmzN8%!3$Y7=pn`cnoK4zFAHsiD+@@7(+aa590%7a^1MLl z(FiSs;95|jHkYB_c(lvdUZxCjzK)VhGoubO}^YgJ)3Im8H!BAiK4~HFE z<%aTte2U7{Wukv1o?tban)U%A0qQV38EPP+D20Mlm<~o1mW{!}076b?YV}$m!3M-k zr-PvckJQ-(**X)rXVPutr`doxZwBwszw9iy%-|czPjnCb0}{Nh=L`B}P??B-8~KUe zfq&QYGo8uk7EC8nk^C;t$H{={x-lPa%1_7;)CM=EFd;(AkltuA8DUms!xV*XxXjQh zyVf%20ZDmYUY^-Rep0Ug%%}ch|5OW~z$a(1J{c3slJN0_w@{3}e-{NO-OnZgHl$MG z4_Cz}lMwqfprDih`=C#3UNxq1-c7FGvJWJAMUq13M3Sc;5|6EW*p+0tX0zZ!Nn*zu zypCB(de~=^K=W*JLlEFS?8W3J*XwL3*>wR5@v&7Sk@(9bZ_%!byH@cWH=hLdMAA}( z2ys2>#6W~AXdguT4ivV$=AT;i6bw+jmXP)o&qhxgulxZ>Ue%`NxtrB3?me*g4$AEr^0nYsBrmsXH9XoaW%`vXlw+XB+)7jC zHdnw~(t?Zh*R95$)9jH|gyH+o-&118At3L9BMwmZ-Jl#*tmw!`EqH&{6=-(_+F`=O zXQe#$mDTS0Ru8Ra2UqEgzy!WvOA~B{E<$k$#EAMeIsrvF1rF-hTySgp-B7}bY+Pk%Yk4%>eFhT>b-P;m}xTJz$EuRL~d zn(BF=QeLNOyNN11dd(N`xINIW&k$?Z8->X=mtPg{TFYU()@~q@-&%vuN$LJ3bCD3w;Kp7_<-p>+kh6|1kGK0P#@ii#flq;GaI|rQ zq+e39N7mDnJN^$!I>md2MjZ!{sttt=Kwz>1?GP&^`|WiMneYuF;{yAIb?z~+<4fxU z!#r9_tA+?|4Q05sk}ZAqiV zHu;M9Gx-Ydu*I13!lSZyLgvBp;0YNV=^yebaK#|7@EsXlIw{i?-1p^8E)V-18HS@; zI%E!1uV@3+;HdCN*|x}dF8=5G6' - 0x3e + DB 0x0e, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04 ; '?' - 0x3f + DB 0x0e, 0x11, 0x10, 0x16, 0x15, 0x15, 0x0e ; '@' - 0x40 + DB 0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11 ; 'A' - 0x41 + DB 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f ; 'B' - 0x42 + DB 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e ; 'C' - 0x43 + DB 0x07, 0x09, 0x11, 0x11, 0x11, 0x09, 0x07 ; 'D' - 0x44 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f ; 'E' - 0x45 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01 ; 'F' - 0x46 + DB 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x1e ; 'G' - 0x47 + DB 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 ; 'H' - 0x48 + DB 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e ; 'I' - 0x49 + DB 0x1c, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06 ; 'J' - 0x4a + DB 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 ; 'K' - 0x4b + DB 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f ; 'L' - 0x4c + DB 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11 ; 'M' - 0x4d + DB 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11 ; 'N' - 0x4e + DB 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; 'O' - 0x4f + DB 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01 ; 'P' - 0x50 + DB 0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16 ; 'Q' - 0x51 + DB 0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11 ; 'R' - 0x52 + DB 0x1e, 0x01, 0x01, 0x0e, 0x10, 0x10, 0x0f ; 'S' - 0x53 + DB 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; 'T' - 0x54 + DB 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; 'U' - 0x55 + DB 0x11, 0x11, 0x11, 0x11, 0x0a, 0x0a, 0x04 ; 'V' - 0x56 + DB 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a ; 'W' - 0x57 + DB 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 ; 'X' - 0x58 + DB 0x11, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04 ; 'Y' - 0x59 + DB 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f ; 'Z' - 0x5a + DB 0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e ; '[' - 0x5b + DB 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00 ; '\' - 0x5c + DB 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e ; ']' - 0x5d + DB 0x0e, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00 ; '^' - 0x5r + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f ; '_' - 0x5f + DB 0x1c, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00 ; '`' - 0x60 + DB 0x00, 0x00, 0x0e, 0x10, 0x1e, 0x13, 0x1e ; 'a' - 0x61 + DB 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x0f ; 'b' - 0x62 + DB 0x00, 0x00, 0x0e, 0x01, 0x01, 0x01, 0x0e ; 'c' - 0x63 + DB 0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x1e ; 'd' - 0x64 + DB 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e ; 'e' - 0x65 + DB 0x18, 0x04, 0x04, 0x0e, 0x04, 0x04, 0x04 ; 'f' - 0x66 + DB 0x00, 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x0e ; 'g' - 0x67 + DB 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x11 ; 'h' - 0x68 + DB 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04 ; 'i' - 0x69 + DB 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x06 ; 'j' - 0x6a + DB 0x01, 0x01, 0x09, 0x05, 0x03, 0x05, 0x09 ; 'k' - 0x6b + DB 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08 ; 'l' - 0x6c + DB 0x00, 0x00, 0x0f, 0x15, 0x15, 0x15, 0x15 ; 'm' - 0x6d + DB 0x00, 0x00, 0x09, 0x13, 0x11, 0x11, 0x11 ; 'n' - 0x6e + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e ; 'o' - 0x6f + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x0f, 0x01 ; 'p' - 0x70 + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x1e, 0x10 ; 'q' - 0x71 + DB 0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01 ; 'r' - 0x72 + DB 0x00, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f ; 's' - 0x73 + DB 0x04, 0x04, 0x0e, 0x04, 0x04, 0x04, 0x18 ; 't' - 0x74 + DB 0x00, 0x00, 0x11, 0x11, 0x11, 0x19, 0x16 ; 'u' - 0x75 + DB 0x00, 0x00, 0x11, 0x11, 0x0a, 0x0a, 0x04 ; 'v' - 0x76 + DB 0x00, 0x00, 0x11, 0x15, 0x15, 0x15, 0x0a ; 'w' - 0x77 + DB 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11 ; 'x' - 0x78 + DB 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0c ; 'y' - 0x79 + DB 0x00, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f ; 'z' - 0x7a + DB 0x0c, 0x02, 0x02, 0x01, 0x02, 0x02, 0x0c ; '{' - 0x7b + DB 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; '|' - 0x7c + DB 0x03, 0x04, 0x04, 0x08, 0x04, 0x04, 0x03 ; '}' - 0x7d + DB 0x00, 0x02, 0x15, 0x0a, 0x15, 0x08, 0x00 ; '~' - 0x7e + DB 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15 ; [DEL] - 0x7f + +; 64 symbols 6x7, with codes 0x40..0x7f KOI-7 H1 +m_font_cp1: + DB 0x00, 0x00, 0x09, 0x15, 0x17, 0x15, 0x09 ; ю - 0x40 + DB 0x00, 0x00, 0x06, 0x08, 0x0e, 0x09, 0x16 ; а - 0x41 + DB 0x07, 0x02, 0x04, 0x0e, 0x09, 0x09, 0x06 ; б - 0x42 DIFF + DB 0x00, 0x00, 0x09, 0x09, 0x09, 0x1f, 0x10 ; ц - 0x43 + DB 0x03, 0x04, 0x08, 0x0e, 0x09, 0x09, 0x06 ; д - 0x44 DIFF + DB 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x1e ; е - 0x45 + DB 0x00, 0x04, 0x0e, 0x15, 0x15, 0x0e, 0x04 ; ф - 0x46 + DB 0x00, 0x00, 0x0f, 0x09, 0x01, 0x01, 0x01 ; г - 0x47 + DB 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11 ; х - 0x48 + DB 0x00, 0x00, 0x11, 0x19, 0x15, 0x13, 0x11 ; и - 0x49 + DB 0x0a, 0x04, 0x11, 0x19, 0x15, 0x13, 0x11 ; й - 0x4a + DB 0x00, 0x00, 0x11, 0x09, 0x07, 0x09, 0x11 ; к - 0x4b + DB 0x00, 0x00, 0x1c, 0x12, 0x12, 0x12, 0x11 ; л - 0x4c + DB 0x00, 0x00, 0x11, 0x1b, 0x15, 0x11, 0x11 ; м - 0x4d + DB 0x00, 0x00, 0x11, 0x11, 0x1f, 0x11, 0x11 ; н - 0x4e + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e ; о - 0x4f + DB 0x00, 0x00, 0x1f, 0x11, 0x11, 0x11, 0x11 ; п - 0x50 + DB 0x00, 0x00, 0x1e, 0x11, 0x1e, 0x14, 0x12 ; я - 0x51 + DB 0x00, 0x00, 0x07, 0x09, 0x07, 0x01, 0x01 ; р - 0x52 + DB 0x00, 0x00, 0x0e, 0x01, 0x01, 0x01, 0x0e ; с - 0x53 + DB 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04 ; т - 0x54 + DB 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0e ; у - 0x55 + DB 0x00, 0x00, 0x15, 0x15, 0x0e, 0x15, 0x15 ; ж - 0x56 + DB 0x00, 0x00, 0x03, 0x05, 0x07, 0x09, 0x07 ; в - 0x57 + DB 0x00, 0x00, 0x01, 0x01, 0x07, 0x09, 0x07 ; ь - 0x58 + DB 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x13 ; ы - 0x59 + DB 0x00, 0x00, 0x0e, 0x11, 0x0c, 0x11, 0x0e ; з - 0x5a + DB 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1f ; ш - 0x5b + DB 0x00, 0x00, 0x07, 0x08, 0x0e, 0x08, 0x07 ; э - 0x5c + DB 0x00, 0x00, 0x15, 0x15, 0x15, 0x1f, 0x10 ; щ - 0x5d + DB 0x00, 0x00, 0x09, 0x09, 0x0e, 0x08, 0x08 ; ч - 0x5e + DB 0x00, 0x00, 0x06, 0x05, 0x0c, 0x14, 0x0c ; ъ - 0x5f + DB 0x09, 0x15, 0x15, 0x17, 0x15, 0x15, 0x09 ; Ю - 0x60 + DB 0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11 ; А - 0x61 + DB 0x1f, 0x11, 0x01, 0x0f, 0x11, 0x11, 0x1f ; Б - 0x62 + DB 0x09, 0x09, 0x09, 0x09, 0x09, 0x1f, 0x10 ; С - 0x63 + DB 0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x1f, 0x11 ; Д - 0x64 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f ; Е - 0x65 + DB 0x04, 0x0e, 0x15, 0x15, 0x15, 0x0e, 0x04 ; Ф - 0x66 + DB 0x1f, 0x11, 0x01, 0x01, 0x01, 0x01, 0x01 ; Г - 0x67 + DB 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 ; Х - 0x68 + DB 0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11 ; И - 0x69 + DB 0x04, 0x15, 0x11, 0x19, 0x15, 0x13, 0x11 ; Й - 0x6a + DB 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 ; К - 0x6b + DB 0x1c, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11 ; Л - 0x6c + DB 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11 ; М - 0x6d + DB 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 ; Н - 0x6e + DB 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; О - 0x6f + DB 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 ; П - 0x70 + DB 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x12, 0x11 ; Я - 0x71 + DB 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x01, 0x01 ; Р - 0x72 + DB 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e ; С - 0x73 + DB 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; Т - 0x74 + DB 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e ; У - 0x75 + DB 0x15, 0x15, 0x15, 0x0e, 0x15, 0x15, 0x15 ; Ж - 0x76 + DB 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f ; В - 0x77 + DB 0x01, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x0f ; Ь - 0x78 + DB 0x11, 0x11, 0x11, 0x13, 0x15, 0x15, 0x13 ; Ы - 0x79 + DB 0x0e, 0x11, 0x10, 0x0c, 0x10, 0x11, 0x0e ; З - 0x7a + DB 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f ; Ш - 0x7b + DB 0x0e, 0x11, 0x10, 0x1c, 0x10, 0x11, 0x0e ; Э - 0x7c + DB 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x10 ; Щ - 0x7d + DB 0x11, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x10 ; Ч - 0x7e + DB 0x1f, 0x15, 0x1f, 0x15, 0x1f, 0x15, 0x1f ; [DEL] - 0x7f diff --git a/MON_r8_9c6c6546/io.inc b/MON_r8_9c6c6546/io.inc new file mode 100644 index 0000000..d884e0b --- /dev/null +++ b/MON_r8_9c6c6546/io.inc @@ -0,0 +1,132 @@ +; ======================================================= +; Ocean-240.2 +; Computer with FDC variant. +; IO Ports definitions +; +; By Romych 2025-09-09 +; ======================================================= + + IFNDEF _IO_PORTS + DEFINE _IO_PORTS + +; ------------------------------------------------------- +; КР580ВВ55 DD79 +; ------------------------------------------------------- +; Port A - User port A +USR_DD79PA EQU 0x00 + +; Port B - User port B +USR_DD79PB EQU 0x01 + +; Port C - User port C +USR_DD79PC EQU 0x02 + +; Config: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1] +USR_DD79CTR EQU 0x03 + +; ------------------------------------------------------- +; КР1818ВГ93 +; ------------------------------------------------------- +; CMD +FDC_CMD EQU 0x20 + +; TRACK +FDC_TRACK EQU 0x21 + +; SECTOR +FDC_SECT EQU 0x22 + +; DATA +FDC_DATA EQU 0x23 + +; +FDC_WAIT EQU 0x24 + +; Controller port +FLOPPY EQU 0x25 + + +; ------------------------------------------------------- +; КР580ВВ55 DD78 +; ------------------------------------------------------- +; Port A - Keyboard Data +KBD_DD78PA EQU 0x40 + +; Port B - JST3,SHFT,CTRL,ACK,TAPE5,TAPE4,GK,GC +KBD_DD78PB EQU 0x41 + +; Port C - [PC7..0] +KBD_DD78PC EQU 0x42 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +KBD_DD78CTR EQU 0x43 + + +; ------------------------------------------------------- +; КР580ВИ53 DD70 +; ------------------------------------------------------- +; Counter 1 +TMR_DD70C1 EQU 0x60 + +; Counter 2 +TMR_DD70C2 EQU 0x61 + +; Counter 3 +TMR_DD70C3 EQU 0x62 + +; Config: [sc1,sc0][rl1,rl0][m2,m1,m0][bcd] +; sc - timer, rl=01-LSB, 10-MSB, 11-LSB+MSB +; mode 000 - int on fin, +; 001 - one shot, +; x10 - rate gen, +; x11-sq wave +TMR_DD70CTR EQU 0x63 + +; Programable Interrupt controller PIC KR580VV59 +PIC_DD75RS EQU 0x80 +PIC_DD75RM EQU 0x81 + +; ------------------------------------------------------- +; КР580ВВ51 DD72 +; ------------------------------------------------------- +; Data +UART_DD72RD EQU 0xA0 + +; [RST,RQ_RX,RST_ERR,PAUSE,RX_EN,RX_RDY,TX_RDY] +UART_DD72RR EQU 0xA1 + +; ------------------------------------------------------- +; КР580ВВ55 DD17 +; ------------------------------------------------------- +; Port A - VShift[8..1] +SYS_DD17PA EQU 0xC0 + +; Port B - [ROM14,13][REST][ENROM-][A18,17,16][32k] +SYS_DD17PB EQU 0xC1 + +; Port C - HShift[HS5..1,SB3..1] +SYS_DD17PC EQU 0xC2 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +SYS_DD17CTR EQU 0xC3 + +; ------------------------------------------------------- +; КР580ВВ55 DD67 +; ------------------------------------------------------- +; Port A - LPT Data +LPT_DD67PA EQU 0xE0 + +; Port B - [VSU,C/M,FL3..1,COL3..1] +VID_DD67PB EQU 0xE1 + +; Port C - [USER3..1,STB-LP,BELL,TAPE3..1] +DD67PC EQU 0xE2 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +DD67CTR EQU 0xE3 + + ENDIF \ No newline at end of file diff --git a/MON_r8_9c6c6546/m_vars.inc b/MON_r8_9c6c6546/m_vars.inc new file mode 100644 index 0000000..578bddd --- /dev/null +++ b/MON_r8_9c6c6546/m_vars.inc @@ -0,0 +1,101 @@ +; ======================================================= +; Ocean-240.2 +; Module M_VARS - Monitor variables +; RAM Range: 0xBA09-0xBFFF +; +; Disassembled by Romych 2025-02-05 +; ======================================================= + + IFNDEF _M_VARS + DEFINE _M_VARS + + MODULE M_VARS + ORG 0xbf00 + +buffer DS 128 ; 0xbf00 search text or buffer to search? + DS 36 +paint_stack EQU $ ; 0xbfa4 + DS 32 +stack1: EQU $ ; 0xbfc4 + DS 1 +paint_var1 DS 1 ; 0xbfc5 +paint_var2 DS 1 ; 0xbfc6 +paint_var3 DS 1 ; 0xbfc7 +paint_var4 DS 1 ; 0xbfc8 +paint_var5 DS 1 ; 0xbfc9 +paint_y DS 1 ; 0xbfca +paint_var7 DS 1 ; 0xbfcb +cmp_color DS 1 ; 0xbfcc +paint_sp_save DS 2 + +; Right pixel mask ex: 11111000 +pixel_mask_r DS 1 ; 0xbfcf +tmp_color DS 1 ; 0xbfd0 +rect_var2 DS 1 ; 0xbfd1 +stack_0 EQU $ +rect_var3 DS 1 ; 0xbfd2 +esc_mode DS 1 ; 0xbfd3 +esc_cmd DS 1 ; 0xbfd4 + +esc_param_cnt DS 1 ; 0xbfd5 +esc_param DS 7 ; 0xbfd6 + +; Left inverse pixel mask ex: 00011111 +pixel_mask_l_i DS 1 +; Right inverse pixel mask ex: 00011111 +pixel_mask_r_i DS 1 +; Left pixel mask ex: 11100000 +pixel_mask_l DS 1 + +; Current screen mode, bit 3 - hide/show cursor, bit 4 - only 20 rows +screen_mode DS 1 ; 0xbfe0 +cursor_row DS 1 ; 0xbfe1 Cursor Y position +cursor_col DS 1 ; 0xbfe2 Cursor X position +curr_color DS 2 ; 0xbfe3 Current color low and hi bytes +esc_hex_cmd: +row_shift DS 1 ; 0xbfe5 +codepage DS 1 ; 0xbfe6 + + +cur_palette DS 1 ; 0xbfe7 00bbbfff - background and foreground colors +beep_period DS 2 ; 0xbfe8 +beep_duration DS 2 ; 0xbfea +pix_shift DS 1 ; 0xbfec +strobe_state DS 1 ; 0xbfed +ul_var0 DS 1 ; 0xbfee +ul_A_var1 DS 1 ; 0xbfef +ul_B_var2 DS 1 ; 0xbff0 +ul_var3 DS 1 ; 0xbff1 +ul_A_var4 DS 1 ; 0xbff2 +ul_B_var5 DS 1 ; 0xbff3 +ul_var6 DS 1 ; 0xbff4 +esc_var0 DS 1 ; 0xbff5 +esc_var1 DS 1 ; 0xbff6 +esc_var2 DS 1 ; 0xbff7 +esc_var3 DS 1 ; 0xbff8 + DS 1 ; 0xbff9 + DS 1 ; 0xbffa + DS 1 ; 0xbffb + DS 1 ; 0xbffc + DS 1 ; 0xbffd + DS 1 ; 0xbffe + DS 1 ; 0xbfff + + ASSERT stack1 = 0xbfc4 + ASSERT buffer = 0xbf00 + ASSERT paint_var1 = 0xbfc5 + ASSERT pixel_mask_r = 0xbfcf + ASSERT stack_0 = 0xbfd2 + ASSERT esc_mode = 0xbfd3 + ASSERT screen_mode = 0xbfe0 + ASSERT cur_palette = 0xbfe7 + ASSERT ul_var0 = 0xbfee + ASSERT paint_stack = 0xbfa4 + ASSERT esc_var3 = 0xbff8 + + ;DISPLAY "screen_mode: ", /H, screen_mode + ;DISPLAY "fn48_var1: ", /H, fn48_var1 + + ENDMODULE + + ENDIF diff --git a/MON_r8_9c6c6546/mon_only.map b/MON_r8_9c6c6546/mon_only.map new file mode 100644 index 0000000..04f9873 --- /dev/null +++ b/MON_r8_9c6c6546/mon_only.map @@ -0,0 +1,449 @@ +MONITOR.mon_start 0xe000 f +MONITOR.mon_hexb 0xe003 f +MONITOR.non_con_status 0xe006 f +MONITOR.mon_con_in 0xe009 f +MONITOR.mon_con_out 0xe00c f +MONITOR.mon_serial_in 0xe00f f +MONITOR.mon_serial_out 0xe012 f +MONITOR.mon_char_print 0xe015 f +MONITOR.mon_tape_read 0xe018 f +MONITOR.mon_tape_write 0xe01b f +MONITOR.mon_ram_disk_read 0xe01e f +MONITOR.mon_ram_disk_write 0xe021 f +MONITOR.mon_tape_read_ram 0xe024 f +MONITOR.mon_tape_write_ram 0xe027 f +MONITOR.mon_tape_wait 0xe02a f +MONITOR.mon_tape_detect 0xe02d f +MONITOR.mon_read_floppy 0xe030 f +MONITOR.mon_write_floppy 0xe033 f +MONITOR.mon_out_str_z 0xe036 f +MONITOR.m_start 0xe051 f +MONITOR.m_start.fill_video 0xe06c f +MONITOR.m_start.conf_uart 0xe0a7 f +MONITOR.m_start.conf_pic 0xe0ba f +MONITOR.m_out_strz 0xe0f1 f +MONITOR.mgs_system_nf 0xe0fc f +MONITOR.m_sys_halt 0xe111 f +MONITOR.m_con_status 0xe112 f +MONITOR.m_serial_in 0xe11c f +MONITOR.m_con_in 0xe128 f +MONITOR.m_serial_out 0xe13d f +MONITOR.m_char_print 0xe148 f +MONITOR.m_char_print.wait_lp 0xe157 f +MONITOR.m_con_out 0xe163 f +MONITOR.m_con_out_int 0xe16d f +MONITOR.get_esc_param 0xe187 f +MONITOR.esc_no_draw_fn 0xe1c1 f +MONITOR.esc_exit 0xe1c6 f +MONITOR.esc_params_tab 0xe1cb f +MONITOR.esc_handler_tab 0xe1db f +MONITOR.esc_set_beep 0xe1f9 f +MONITOR.esc_set_cursor2 0xe20e f +MONITOR.esc_print_screen 0xe211 f +MONITOR.esc_print_screen.chk_keys 0xe220 f +MONITOR.esc_print_screen.no_keys 0xe22d f +MONITOR.m_print_hor_line 0xe23a f +MONITOR.m_print_hor_line.print_next_col 0xe248 f +MONITOR.m_print_cmd 0xe276 f +MONITOR.m_print_cmd.print_nxt 0xe277 f +MONITOR.m_print_cmd.cmd_end 0xe285 f +MONITOR.m_print_vert_7pix 0xe287 f +MONITOR.cmd_esc_inc_Y2 0xe2a5 f +MONITOR.cmd_esc_set_X0 0xe2a9 f +MONITOR.cmd_esc_set_X 0xe2ae f +MONITOR.cmd_esc_print_col 0xe2b1 f +MONITOR.m_get_7vpix 0xe2b4 f +MONITOR.m_get_7vpix.calc_pix_no 0xe2be f +MONITOR.m_get_7vpix.for_all_pix 0xe2dc f +MONITOR.m_get_7vpix.all_shifted 0xe2e9 f +MONITOR.m_get_7vpix.not_1_1 0xe2f2 f +MONITOR.m_get_7vpix.not_1_2 0xe2fa f +MONITOR.esc_set_palette 0xe2fe f +MONITOR.esp_no_colr 0xe313 f +MONITOR.esc_set_charset 0xe317 f +MONITOR.m_get_glyph 0xe320 f +MONITOR.m_get_glyph.cp_rus 0xe340 f +MONITOR.m_get_glyph.cp_common 0xe344 f +MONITOR.m_print_no_esc 0xe349 f +MONITOR.m_print_no_esc.l1 0xe377 f +MONITOR.m_print_no_esc.l2 0xe381 f +MONITOR.m_print_no_esc.l3 0xe389 f +MONITOR.m_print_no_esc.l4 0xe391 f +MONITOR.m_print_no_esc.l5 0xe396 f +MONITOR.m_print_no_esc.sym_draw 0xe39a f +MONITOR.m_print_no_esc.pne_l7 0xe3a5 f +MONITOR.m_print_no_esc.pne_l8 0xe3aa f +MONITOR.m40_rt 0xe3ee f +MONITOR.m40_wrap_rt 0xe3f9 f +MONITOR.m40_lf 0xe405 f +MONITOR.m40_bksp 0xe40f f +MONITOR.m40_bksp.wrap 0xe41d f +MONITOR.m40_up 0xe421 f +MONITOR.m40_up.up_no_minus 0xe429 f +MONITOR.m20_tab 0xe42b f +MONITOR.calc_addr_40 0xe439 f +MONITOR.calc_addr_40.l1 0xe454 f +MONITOR.calc_addr_40.l2 0xe45a f +MONITOR.m2_lf 0xe464 f +MONITOR.m2_lf.lf_nowr 0xe46e f +MONITOR.m2_lf.cas_l5 0xe47b f +MONITOR.m2_lf.cas_l6 0xe480 f +MONITOR.m2_lf.cas_l7 0xe496 f +MONITOR.m2_lf.cas_l8 0xe49b f +MONITOR.m20_bksp 0xe4ab f +MONITOR.mp_mode_64 0xe4b8 f +MONITOR.mp_mode_64.next_row 0xe4d3 f +MONITOR.m64_rt 0xe4e7 f +MONITOR.m64_lf 0xe4f0 f +MONITOR.scroll_up 0xe4fa f +MONITOR.scroll_up.next_row 0xe512 f +MONITOR.scroll_up.next_col 0xe514 f +MONITOR.m64_bs 0xe524 f +MONITOR.m64_up 0xe52f f +MONITOR.m64_up.no_wrap 0xe537 f +MONITOR.m64_tab 0xe539 f +MONITOR.mp_mode_80 0xe545 f +MONITOR.mp_mode_80.l1 0xe55e f +MONITOR.mp_mode_80.l2 0xe56d f +MONITOR.mp_mode_80.l3 0xe58e f +MONITOR.mp_mode_80.l4 0xe5b3 f +MONITOR.mp_mode_80.l5 0xe5b4 f +MONITOR.mp_mode_80.l6 0xe5c4 f +MONITOR.m80_rt 0xe5cf f +MONITOR.m80_col_wrap 0xe5da f +MONITOR.m80_lf 0xe5de f +MONITOR.m80_bs 0xe5e8 f +MONITOR.m80_bs.wrap 0xe5f6 f +MONITOR.m80_up 0xe5fa f +MONITOR.m80_up.no_wrap 0xe602 f +MONITOR.m80_tab 0xe604 f +MONITOR.calc_addr_80 0xe612 f +MONITOR.mns_l1 0xe62d f +MONITOR.mns_ep_fm_0 0xe633 f +MONITOR.m_clear_screen 0xe639 f +MONITOR.m_clear_screen.fill_scrn 0xe652 f +MONITOR.m_clear_screen.mono_mode 0xe669 f +MONITOR.m_cursor_home 0xe66c f +MONITOR.m_clear_20_rows 0xe679 f +MONITOR.m_clear_20_rows.next_row 0xe683 f +MONITOR.m_clear_20_rows.next_col 0xe688 f +MONITOR.m_draw_cursor 0xe69a f +MONITOR.m_draw_cursor.dc_rt2 0xe6cf f +MONITOR.m_draw_cursor.dc_mid 0xe6d7 f +MONITOR.m_draw_cursor.dc_lt 0xe6dd f +MONITOR.m_draw_cursor.dc_rt1 0xe6e3 f +MONITOR.m_draw_cursor.dc_put 0xe6e6 f +MONITOR.m_draw_cursor.dc_mode_64 0xe703 f +MONITOR.m_draw_cursor.cur_64_next 0xe721 f +MONITOR.m_draw_cursor.dc_mode_80 0xe72f f +MONITOR.m_draw_cursor.dc_1_byte 0xe75e f +MONITOR.m_draw_cursor.dc_2_byte 0xe769 f +MONITOR.m_draw_cursor.dc_80_end 0xe776 f +MONITOR.m_handle_esc_code 0xe77c f +MONITOR.m_handle_control_code 0xe78a f +MONITOR.handle_cc_common 0xe7c4 f +MONITOR.handle_cc_common.handle_cc_mono 0xe7ff f +MONITOR.handle_cc_80x25 0xe833 f +MONITOR.m_beep 0xe85a f +MONITOR.m_bell_cont 0xe86f f +MONITOR.m_bell_wait_tmr1 0xe879 f +MONITOR.m_bell_wait_tmr2 0xe886 f +MONITOR.esc_set_cursor 0xe890 f +MONITOR.esc_set_cursor.mode_40 0xe8bf f +MONITOR.esc_set_cursor.mode_80 0xe8ca f +MONITOR.esc_set_cursor.common 0xe8d2 f +MONITOR.esc_le_24 0xe8df f +MONITOR.esc_set_vmode 0xe8e9 f +MONITOR.esc_set_vmode.set_color_mode 0xe90f f +MONITOR.esc_set_vmode.skip_for_mono_mode 0xe911 f +MONITOR.esc_set_vmode.draw_cursor 0xe91a f +MONITOR.esc_set_vmode.cursor_hide 0xe91e f +MONITOR.esc_set_vmode.cursor_show 0xe928 f +MONITOR.esc_set_color 0xe92f f +MONITOR.m_set_color 0xe932 f +MONITOR.m_print_at_xy 0xe943 f +MONITOR.m_print_at_xy.mode_sp 0xe986 f +MONITOR.m_print_at_xy.out_sp 0xe99b f +MONITOR.m_print_at_xy.next_line 0xe9a2 f +MONITOR.m_print_at_xy.l04 0xe9af f +MONITOR.m_print_at_xy.l05 0xe9b4 f +MONITOR.m_print_at_xy.sprites_en 0xe9e2 f +MONITOR.mode2_exit 0xe9e6 f +MONITOR.co_ex_l08 0xe9ed f +MONITOR.out_no_xor 0xe9f1 f +MONITOR.out_no_xor.l10 0xe9fe f +MONITOR.out_no_xor.l11 0xea03 f +MONITOR.game_sprite_tab 0xea39 f +MONITOR.calc_px_addr 0xeb51 f +MONITOR.esc_draw_fill_rect 0xeb64 f +MONITOR.esc_draw_fill_rect.non_zero_h 0xeb73 f +MONITOR.esc_draw_fill_rect.shift_mask_l 0xeb78 f +MONITOR.esc_draw_fill_rect.shift_mask_r 0xeb8d f +MONITOR.esc_draw_fill_rect.next_line 0xebb7 f +MONITOR.esc_draw_fill_rect.rectangle_xor 0xebc6 f +MONITOR.esc_draw_fill_rect.edf_l6 0xebd5 f +MONITOR.esc_draw_fill_rect.next_8px 0xebdf f +MONITOR.esc_draw_fill_rect.w_ne_0 0xebe0 f +MONITOR.esc_draw_fill_rect.r_mask 0xebf6 f +MONITOR.esc_draw_fill_rect.next_full 0xebfc f +MONITOR.esc_draw_fill_rect.complete 0xec0b f +MONITOR.esc_paint 0xec18 f +MONITOR.esc_paint.l1 0xec57 f +MONITOR.ep_fm_0 0xec8b f +MONITOR.ep_task_end 0xec9a f +MONITOR.ep_l4 0xecb5 f +MONITOR.ep_l5 0xecbd f +MONITOR.ep_l6 0xecc5 f +MONITOR.ep_f_fast 0xecd7 f +MONITOR.ep_l8 0xece5 f +MONITOR.ep_l9 0xed1d f +MONITOR.ep_l10 0xed2c f +MONITOR.ep_l11 0xed3d f +MONITOR.paint_find_next_right 0xed77 f +MONITOR.paint_find_next_right.l1 0xed84 f +MONITOR.paint_find_next_right.l2 0xed90 f +MONITOR.paint_find_next_left 0xed9a f +MONITOR.paint_find_next_left.l1 0xeda7 f +MONITOR.paint_find_next_left.l2 0xedb3 f +MONITOR.ep_l12 0xedbd f +MONITOR.ep_l13 0xedd6 f +MONITOR.ep_l14 0xede8 f +MONITOR.ep_l15 0xedf1 f +MONITOR.ep_l16 0xedfa f +MONITOR.paint_find_right 0xedfd f +MONITOR.paint_find_right.in_byte 0xee0a f +MONITOR.paint_find_left 0xee18 f +MONITOR.paint_find_left.in_byte 0xee24 f +MONITOR.get_pixel 0xee32 f +MONITOR.get_pixel.bit1_set 0xee48 f +MONITOR.get_pixel.bit2_set 0xee57 f +MONITOR.get_pixel.bit12_set 0xee5f f +MONITOR.paint_task 0xee67 f +MONITOR.paint_task.lmp_mask 0xee7e f +MONITOR.paint_task.rmp_mask 0xee97 f +MONITOR.paint_task.lmi_mask 0xeea3 f +MONITOR.paint_task.rmi_mask 0xeeac f +MONITOR.paint_exit 0xeec6 f +MONITOR.draw_line_h 0xeed1 f +MONITOR.draw_line_h.next_byte 0xeedc f +MONITOR.draw_line_h.width_ne0 0xeedd f +MONITOR.draw_line_h.r_mask 0xeef5 f +MONITOR.draw_line_h.full_8 0xeefb f +MONITOR.draw_line_h.complete 0xef06 f +MONITOR.esc_draw_line 0xef0b f +MONITOR.esc_draw_line.x1_le_x2 0xef1b f +MONITOR.esc_draw_line.pos_height 0xef2b f +MONITOR.esc_draw_line.next_16 0xef45 f +MONITOR.esc_draw_line.edl_l4 0xef51 f +MONITOR.esc_draw_line.edl_l5 0xef54 f +MONITOR.esc_draw_line.roll_l 0xef67 f +MONITOR.esc_draw_line.edl_l7 0xef6e f +MONITOR.esc_draw_line.next_up 0xef89 f +MONITOR.esc_draw_line.next_down 0xef9f f +MONITOR.esc_draw_line.is_last 0xefb5 f +MONITOR.esc_draw_line.edl_l11 0xefc3 f +MONITOR.esc_draw_line.width0 0xefcb f +MONITOR.esc_draw_line.edl_l13 0xefd1 f +MONITOR.esc_draw_line.next_row_up 0xefe5 f +MONITOR.esc_draw_line.next_row_down 0xeffb f +MONITOR.close_vram_ret 0xf011 f +MONITOR.height0 0xf016 f +MONITOR.height0.len_ne0 0xf01e f +MONITOR.height0.edl_l19 0xf023 f +MONITOR.height0.next_col 0xf033 f +MONITOR.height0.edl_l21 0xf048 f +MONITOR.esc_draw_dot 0xf052 f +MONITOR.edd_l1 0xf05b f +MONITOR.edd_ep_fm_0 0xf084 f +MONITOR.edd_ep_task_end 0xf09d f +MONITOR.esc_picture 0xf0a4 f +MONITOR.pict_sub1 0xf0d6 f +MONITOR.pict_clr 0xf0f3 f +MONITOR.ehd_l1 0xf104 f +MONITOR.m_fn_39 0xf10f f +MONITOR.m_fn_39.l1 0xf12e f +MONITOR.m_fn_39.l2 0xf148 f +MONITOR.m_fn_39.l3 0xf15f f +MONITOR.get_image_hdr 0xf177 f +MONITOR.esc_get_put_image 0xf1b5 f +MONITOR.get_image 0xf1e1 f +MONITOR.get_image.next_row 0xf1e3 f +MONITOR.get_image.l2 0xf1f2 f +MONITOR.put_image 0xf201 f +MONITOR.put_image.next_row 0xf203 f +MONITOR.put_image.l2 0xf213 f +MONITOR.img_task_end 0xf21e f +MONITOR.fn39_sub2 0xf223 f +MONITOR.fn39_sub2.l1 0xf224 f +MONITOR.fn39_sub2.l2 0xf225 f +MONITOR.fn39_sub2.l3 0xf233 f +MONITOR.fn39_sub2.l4 0xf238 f +MONITOR.fn39_sub2.l5 0xf245 f +MONITOR.fn39_sub2.l6 0xf24a f +MONITOR.gih_rt 0xf266 f +MONITOR.gih_rt.l1 0xf289 f +MONITOR.gih_rt.l2 0xf28d f +MONITOR.gih_rt.l3 0xf291 f +MONITOR.gih_bs 0xf2bd f +MONITOR.gih_bs.l1 0xf2dd f +MONITOR.gih_bs.l2 0xf2e9 f +MONITOR.gih_bs.l3 0xf2ed f +MONITOR.gih_ctrl_z 0xf319 f +MONITOR.gih_ctrl_z.l1 0xf32e f +MONITOR.gih_ctrl_z.l2 0xf332 f +MONITOR.gih_ctrl_z.l3 0xf345 f +MONITOR.gih_ctrl_z.l4 0xf34a f +MONITOR.gih_ctrl_z.l5 0xf35a f +MONITOR.gih_up 0xf368 f +MONITOR.gih_up.l1 0xf378 f +MONITOR.gih_up.l2 0xf390 f +MONITOR.gih_up.l3 0xf394 f +MONITOR.gih_up.l4 0xf3a7 f +MONITOR.gih_up.l5 0xf3ac f +MONITOR.gih_up.l6 0xf3bc f +MONITOR.pict_sub2 0xf3ca f +MONITOR.pict_sub2.l1 0xf3f2 f +MONITOR.pict_sub2.l2 0xf3f7 f +MONITOR.pict_sub2.l3 0xf3fb f +MONITOR.pict_sub2.l4 0xf426 f +MONITOR.mov_hl_bc 0xf43b f +MONITOR.mov_hl_bc.next 0xf442 f +MONITOR.esc_draw_circle 0xf44c f +MONITOR.esc_draw_circle.l1 0xf469 f +MONITOR.esc_draw_circle.l2 0xf480 f +MONITOR.esc_draw_circle.l3 0xf4a2 f +MONITOR.dc_draw_8px 0xf4ab f +MONITOR.dc_aspect_ratio_1 0xf4c7 f +MONITOR.dc_aspect_ratio_1.dc_ax_ne0 0xf4d7 f +MONITOR.dc_aspect_ratio_1.dc_ay_ne0 0xf4e0 f +MONITOR.dc_aspect_ratio2 0xf4e7 f +MONITOR.dc_aspect_ratio2.dc_ax_ne0 0xf4f7 f +MONITOR.dc_aspect_ratio2.dc_ay_ne0 0xf500 f +MONITOR.dc_mul_e_h 0xf507 f +MONITOR.dc_mul_e_h.l1 0xf50f f +MONITOR.dc_mul_e_h.l2 0xf514 f +MONITOR.dc_mul_e_h.l3 0xf519 f +MONITOR.dc_mul_e_h.l4 0xf51e f +MONITOR.dc_mul_e_h.l5 0xf523 f +MONITOR.dc_mul_e_h.l6 0xf528 f +MONITOR.dc_mul_e_h.l7 0xf52d f +MONITOR.dc_mul_e_h.l8 0xf532 f +MONITOR.dc_draw_4px_bc 0xf534 f +MONITOR.dc_draw_4px_bc.l1 0xf540 f +MONITOR.dc_draw_4px_bc.l2 0xf54c f +MONITOR.dc_draw_4px_bc.l3 0xf558 f +MONITOR.dc_draw_4px_cb 0xf563 f +MONITOR.dc_draw_4px_cb.l1 0xf56f f +MONITOR.dc_draw_4px_cb.l2 0xf57b f +MONITOR.l3 0xf587 f +MONITOR.dc_put_pixel 0xf592 f +MONITOR.dc_put_pixel.roll 0xf59a f +MONITOR.m_font_cp0 0xf5bc f +MONITOR.m_font_cp1 0xf85c f +MONITOR.conv_nibble 0xfa1c f +MONITOR.m_hexb 0xfa26 f +MONITOR.out_hex 0xfa2f f +MONITOR.m_tape_write_ram2 0xfa36 f +MONITOR.m_tape_write_ram2.cl_stack 0xfa3b f +MONITOR.m_tape_write_ram2.nxt_blk 0xfa5d f +MONITOR.twr2_delay 0xfa73 f +MONITOR.twr2_delay.delay 0xfa76 f +MONITOR.m_tape_read_ram2 0xfa7d f +MONITOR.m_tape_read_ram2.srch_first 0xfa88 f +MONITOR.m_tape_read_ram2.rd_next 0xfaa6 f +MONITOR.m_tape_read_ram2.not_found 0xfac5 f +MONITOR.m_tape_read_ram2.rd_error 0xfacc f +MONITOR.m_tape_read_ram2.inv_id 0xfae1 f +MONITOR.m_tape_read_ram2.err_ubi 0xfaed f +MONITOR.m_tape_read_ram2.err_ibu 0xfaf5 f +MONITOR.m_tape_read_ram2.end 0xfaf6 f +MONITOR.out_hexw 0xfafd f +MONITOR.msg_no_start_rec 0xfb08 f +MONITOR.msg_checksum 0xfb18 f +MONITOR.msg_sequence 0xfb22 f +MONITOR.msg_ibg 0xfb2c f +MONITOR.msg_break 0xfb30 f +MONITOR.me_out_strz 0xfb36 f +MONITOR.m_ramdisk_read 0xfb43 f +MONITOR.m_ramdisk_read.read 0xfb55 f +MONITOR.m_ramdisk_write 0xfb6d f +MONITOR.m_ramdisk_write.wr_byte 0xfb7f f +MONITOR.m_tape_write 0xfb97 f +MONITOR.m_tape_write.l1 0xfbae f +MONITOR.m_tape_write.set_lvl 0xfbc0 f +MONITOR.m_tape_write.l2 0xfbd0 f +MONITOR.m_tape_write.next_byte 0xfbee f +MONITOR.m_tape_write.wait_end 0xfc00 f +MONITOR.m_tape_wr_byte 0xfc0e f +MONITOR.m_tape_wr_byte.get_bit 0xfc15 f +MONITOR.m_tape_wr_byte.wait_t 0xfc1b f +MONITOR.m_tape_wr_byte.out_bit 0xfc39 f +MONITOR.m_tape_wr_byte.bit_hi 0xfc41 f +MONITOR.m_tape_wr_byte.out_bit_hi 0xfc5f f +MONITOR.m_tape_read 0xfc67 f +MONITOR.m_tape_read.wait_3_changes 0xfc79 f +MONITOR.m_tape_read.wait_4th_change 0xfc8a f +MONITOR.m_tape_read.wait_f5_marker 0xfc99 f +MONITOR.m_tape_read.read_next_b 0xfcbd f +MONITOR.m_tape_read.checksum_ok 0xfcd6 f +MONITOR.m_tape_read.return 0xfcd7 f +MONITOR.m_tape_read.err_read_blk 0xfcda f +MONITOR.m_tape_read.err_read_id 0xfcde f +MONITOR.m_tape_read.key_pressed 0xfce3 f +MONITOR.m_tape_read_byte 0xfcee f +MONITOR.m_tape_read_byte.next_bit 0xfcf1 f +MONITOR.m_tape_read_byte.ret_err 0xfd06 f +MONITOR.m_read_tape_bit 0xfd08 f +MONITOR.m_read_tape_bit.wait_change 0xfd0d f +MONITOR.read_tape_bit_kbd 0xfd2b f +MONITOR.read_tape_bit_kbd.wait_change 0xfd30 f +MONITOR.read_tape_bit_kbd.key_pressed 0xfd55 f +MONITOR.m_tape_wait 0xfd58 f +MONITOR.m_tape_wait.wait_t4 0xfd5c f +MONITOR.m_tape_wait.wait_next_2ms 0xfd62 f +MONITOR.m_tape_wait.wait_tmr_key 0xfd6d f +MONITOR.m_tape_wait.wait_no_rst4 0xfd86 f +MONITOR.m_tape_wait.key_pressed 0xfd8d f +MONITOR.m_tape_blk_detect 0xfd95 f +MONITOR.fdc_unload_head 0xfd9e f +MONITOR.fdc_unload_head.wait_no_busy 0xfda8 f +MONITOR.fdc_unload_head.tr0_ok 0xfdba f +MONITOR.fdc_unload_head.b1 0xfdc9 f +MONITOR.m_select_drive 0xfdd1 f +MONITOR.m_select_drive.sel_A 0xfddf f +MONITOR.m_select_drive.sel_B 0xfde1 f +MONITOR.m_select_drive.dpar_a 0xfdf6 f +MONITOR.m_select_drive.dpar_b 0xfdf9 f +MONITOR.m_select_drive.l_le 0xfe15 f +MONITOR.delay_136uS 0xfe24 f +MONITOR.delay_b 0xfe26 f +MONITOR.delay_1.4mS 0xfe2b f +MONITOR.m_read_floppy 0xfe30 f +MONITOR.m_write_floppy 0xfe43 f +MONITOR.m_start_seek_track 0xfe56 f +MONITOR.m_start_floppy 0xfe5f f +MONITOR.m_start_floppy.need_m_start 0xfe6b f +MONITOR.m_start_floppy.wait_motor 0xfe76 f +MONITOR.m_start_floppy.wait_rdy1 0xfe7d f +MONITOR.m_start_floppy.long_delay 0xfe8f f +MONITOR.m_start_floppy.mst_exi 0xfe95 f +MONITOR.fdc_init 0xfe97 f +MONITOR.m_fdc_seek_trk 0xfea3 f +MONITOR.m_fdc_seek_trk.drv_b 0xfebc f +MONITOR.m_fdc_seek_trk.cmn 0xfecd f +MONITOR.m_fdc_seek_trk.l1 0xfef5 f +MONITOR.m_fdc_seek_trk.l2 0xff06 f +MONITOR.m_fdc_seek_trk.l3 0xff1d f +MONITOR.m_fdc_seek_trk.l4 0xff20 f +MONITOR.m_fdc_write_bytes 0xff26 f +MONITOR.m_fdc_write_bytes.w_next 0xff29 f +MONITOR.m_fdc_read_c_bytes 0xff37 f +MONITOR.m_fdc_read_c_bytes.l1 0xff3d f +MONITOR.m_fdc_read_c_bytes.l2 0xff3f f +MONITOR.fdc_check_status 0xff4b f +MONITOR.fdc_ret 0xff55 f +MONITOR.filler1 0xff56 f +MONITOR.LAST 0xff57 l +MONITOR.CODE_SIZE 0x1f57 l +MONITOR.FILL_SIZE 0xa9 l +MONITOR.FILLER 0xff57 f diff --git a/MON_r8_9c6c6546/monitor.asm b/MON_r8_9c6c6546/monitor.asm new file mode 100644 index 0000000..c669604 --- /dev/null +++ b/MON_r8_9c6c6546/monitor.asm @@ -0,0 +1,5596 @@ +; ====================================================== +; Ocean-240.2 +; Monitor V8 +; crc32: 9c6c6546 +; +; Disassembled by Romych 2026-02-17 +; ====================================================== + + DEVICE NOSLOT64K + + INCLUDE "io.inc" + INCLUDE "equates.inc" + INCLUDE "ram.inc" + INCLUDE "bios_entries.inc" + + OUTPUT mon_E000.bin + + + MODULE MONITOR + + ORG 0xe000 + +; ------------------------------------------------------ +; Monitor Entry points +; ------------------------------------------------------ + +mon_start: JP m_start ; E000 +mon_hexb: JP m_hexb ; E003 +non_con_status: JP m_con_status ; E006 +mon_con_in: JP m_con_in ; E009 +mon_con_out: JP m_con_out ; E00C +mon_serial_in: JP m_serial_in ; E00F +mon_serial_out: JP m_serial_out ; E012 +mon_char_print: JP m_char_print ; E015 +mon_tape_read: JP m_tape_read ; E018 +mon_tape_write: JP m_tape_write ; E01B +mon_ram_disk_read: JP m_ramdisk_read ; E01E +mon_ram_disk_write: JP m_ramdisk_write ; E021 +mon_tape_read_ram: JP m_tape_read_ram2 ; E024 +mon_tape_write_ram: JP m_tape_write_ram2 ; E027 +mon_tape_wait: JP m_tape_wait ; E02A +mon_tape_detect: JP m_tape_blk_detect ; E02D +mon_read_floppy: JP m_read_floppy ; E030 +mon_write_floppy: JP m_write_floppy ; E033 +mon_out_str_z: JP m_out_strz ; E036 + JP m_fn_39 ; E039 + JP get_image_hdr ; E03C + JP esc_picture ; E03F + JP m_print_at_xy ; E042 + JP esc_draw_fill_rect ; E045 + JP esc_paint ; E048 + JP esc_draw_line ; E04B + JP esc_draw_circle ; E04E + + +; ------------------------------------------------------ +; Init system devices +; ------------------------------------------------------ +m_start: + DI + LD A, 10000000b ; DD17 all ports to out + OUT (SYS_DD17CTR), A ; VV55 Sys CTR + OUT (DD67CTR), A ; VV55 Video CTR + + ; init_kbd_tape + LD A, 0x93 + OUT (KBD_DD78CTR), A + + + LD A, 01111111b ; VSU=0, C/M=1, FL=111, COL=111 + OUT (VID_DD67PB), A ; color mode + LD A, 00000001b + OUT (SYS_DD17PB), A ; Access to VRAM + LD B, 0x0 ; TODO: replace to LD HL, 0x3f00 LD B,L + LD HL, 0x3f00 + LD A, H + ADD A, 0x41 ; A=128 0x80 + + ; Clear memory from 0x3F00 to 0x7FFF +.fill_video: + LD (HL), B + INC HL + CP H + JP NZ, .fill_video + + ;XOR A + LD A, 0 + OUT (SYS_DD17PB), A ; Disable VRAM + LD A, 00000111b + OUT (SYS_DD17PC), A ; pix shift to 7 + LD (M_VARS.pix_shift), A + + XOR A + LD (M_VARS.screen_mode), A + LD (M_VARS.row_shift), A + + ; Set color mode and palette + LD (M_VARS.curr_color+1), A + CPL + LD (M_VARS.curr_color), A + LD A, 00000011b + LD (M_VARS.cur_palette), A + ; VSU=0, C/M=1, FL=000, COL=011 + ; color mode, black border + ; 00-black, 01-red, 10-purple, 11-white + LD A, 01000011b + OUT (VID_DD67PB), A + + ; config LPT + LD A, 0x4 + OUT (DD67PC), A ; bell=1, strobe=0 + LD (M_VARS.strobe_state), A ; store strobe + LD HL, 1024 ; 683us + LD (M_VARS.beep_period), HL + LD HL, 320 ; 213us + LD (M_VARS.beep_duration), HL + +.conf_uart: + ; Config UART + LD A, 11001110b + OUT (UART_DD72RR), A + LD A, 00100101b + OUT (UART_DD72RR), A + + ; Config Timer#1 for UART clock + LD A, 01110110b ; tmr#1, load l+m bin, sq wave + OUT (TMR_DD70CTR), A + + ; 1.5M/20 = 75kHz + LD A, 20 + OUT (TMR_DD70C2), A + XOR A + OUT (TMR_DD70C2), A +.conf_pic: + ; Config PIC + LD A,00010010b ; ICW1 edge trigger, interval 8, sin... + OUT (PIC_DD75RS), A + XOR A + OUT (PIC_DD75RM), A ; ICW2 + CPL + OUT (PIC_DD75RM), A ; ICW3 no slave + LD A,00100000b + OUT (PIC_DD75RS), A ; Non-specific EOI command, End of I... + LD A, PIC_POLL_MODE + OUT (PIC_DD75RS), A ; Poll mode, poll on next RD + + LD A, 0x80 + OUT (KBD_DD78PC), A ; TODO: - Check using this 7th bit + NOP + NOP + XOR A + OUT (KBD_DD78PC), A + + ; Init cursor + LD SP, M_VARS.stack1 + CALL m_draw_cursor + + ; Beep + LD C, ASCII_BELL + CALL m_con_out + + LD A, (BIOS.boot_f) + CP JP_OPCODE + JP Z, BIOS.boot_f + LD HL, mgs_system_nf + CALL m_out_strz + JP m_sys_halt + +; -------------------------------------------------- +; Output ASCIIZ string +; Inp: HL -> string +; -------------------------------------------------- +m_out_strz: + LD C, (HL) + LD A, C + OR A + RET Z + CALL m_con_out + INC HL + JP m_out_strz + +mgs_system_nf: + DB "\r\nSYSTEM NOT FOUND\r\n", 0 + +m_sys_halt: + HALT + +; ------------------------------------------------------ +; Console status +; Out: A = 0 - not ready +; A = 0xFF - ready (key pressed) +; ------------------------------------------------------ +m_con_status: + IN A, (PIC_DD75RS) ; Read PIC status + NOP + AND KBD_IRQ ; Check keyboard request RST1 + LD A, 0 + RET Z ; no key pressed + CPL + RET ; key pressed + +; ------------------------------------------------------ +; Wait and read data from UART +; Out: A - 7 bit data +; ------------------------------------------------------ +m_serial_in: + IN A, (UART_DD72RR) + AND RX_READY + JP Z, m_serial_in ; wait for rx data ready + IN A, (UART_DD72RD) + AND 0x7f ; leave 7 bits + RET + +; ------------------------------------------------------ +; Read key +; Out: A +; ------------------------------------------------------ +m_con_in: + CALL m_con_status + OR A + JP Z, m_con_in ; wait key + IN A, (KBD_DD78PA) ; get key + ;AND 0x7f ; reset hi bit, leave 0..127 code + NOP ; do not reset hi bit + NOP + PUSH AF + ; TODO: Check if it is keyboard ACK + ; PC7 Set Hi (ACK?) + LD A, 0x80 + OUT (KBD_DD78PC), A + ; PC7 Set Lo + XOR A + OUT (KBD_DD78PC), A + POP AF + RET + +; ------------------------------------------------------ +; Send data by UART +; Inp: C - data to transmitt +; ------------------------------------------------------ +m_serial_out: + IN A, (UART_DD72RR) + AND TX_READY + JP Z, m_serial_out ; Wait for TX ready + LD A, C + OUT (UART_DD72RD), A + RET + +; ------------------------------------------------------ +; Send character to printer +; Inp: C - character +; ------------------------------------------------------ +m_char_print: + ; wait printer ready + IN A, (PIC_DD75RS) + AND PRINTER_IRQ + JP Z, m_char_print + + LD A, C + NOP + OUT (LPT_DD67PA), A + ; set LP strobe + LD A, 00010100b + OUT (DD67PC),A + +.wait_lp: + ; wait printer ack + IN A, (PIC_DD75RS) + AND PRINTER_IRQ + JP NZ, .wait_lp + ; remove LP strobe + LD A, 00000100b + OUT (DD67PC), A + RET + +; ------------------------------------------------------ +; Out char to console +; Inp: C - char +; ------------------------------------------------------ +m_con_out: + PUSH HL + PUSH DE + PUSH BC + CALL m_con_out_int + POP BC + POP DE + POP HL + RET + +; ------------------------------------------------------ +; Out char C to console +; ------------------------------------------------------ +m_con_out_int: + LD DE, M_VARS.esc_mode + LD A, (DE) + DEC A + OR A ; TODO: unused (save 1b 4t) + JP M, m_print_no_esc ; esc_mode=0 - standart print no ESC mode + JP NZ, m_print_at_xy ; esc_mode=2 (graphics) + + ; handle ESC param (esc_mode=1) + INC DE ; TODO: replace to INC E E=0xd3 save 2t + LD A, (DE) + OR A + JP P, get_esc_param + LD A, C + AND 0xf ; convert char to command code + LD (DE), A + INC DE ; TODO: replace to INC E E=0xd3 save 2t + XOR A + LD (DE), A + RET + +get_esc_param: + LD HL, M_VARS.esc_cmd + LD B, (HL) ; TODO: replace to INC L L=0xd4 save 2t + INC HL ; HL -> param count + LD A, (HL) + INC A + LD (HL), A + ; store new param + LD E, A + LD D, 0x0 + ADD HL, DE ; HL -> parameter[param_count] + LD (HL), C ; store letter as esc parameter + ; get params count for esc command + LD HL, esc_params_tab + LD E, B ; d=0, b = cmd + ADD HL, DE ; DE - command offset + CP (HL) + ; return if enough + RET M + +;esc_set_mode: + LD HL, M_VARS.esc_cmd + LD A, (HL) + AND 0x0f ; mask (cmd=0..15) + LD E, A + DEC HL ; HL -> esc_mode + OR A + LD (HL), 2 ; mode=2 for cmd=0 + RET Z ; just return, no handler there + + LD D, 0 ; TODO: remove, D already 0 + LD (HL), D ; reset mode to 0 for other + DEC DE ; DE = cmd-1 + +;co_get_hdlr: + ; Calc ESC command handler offset + LD HL, esc_handler_tab + ADD HL, DE + ADD HL, DE + LD E, (HL) + INC HL + LD D, (HL) + ; HL = addr of handler func + EX DE, HL + ; It is 1..4 func DRAW_* func? + CP 0x4 + JP P, esc_no_draw_fn + LD A, (M_VARS.screen_mode) + AND 00000011b + ; If not in graphics mode - exit + JP NZ, esc_exit + +esc_no_draw_fn: + LD DE, esc_exit + PUSH DE + + ; Jump to ESC func handler + JP (HL) + +esc_exit: + XOR A + LD (M_VARS.esc_mode), A + RET + + ; Count of parameters for ESC commands + ; 0xe1cb +esc_params_tab: + DB 3, 5, 4, 3, 1, 2, 1, 1 + DB 1, 2, 1, 5, 5, 7, 6, 4 + +esc_handler_tab: + DW esc_draw_fill_rect ;5 1x1y1x2y2m + DW esc_draw_line ;4 2x1y1x2y2 + DW esc_draw_dot ;3 3xxyy + DW esc_set_color ;1 4N N=1..4 + DW esc_set_cursor ;2 5rc r-Row, c-Col + DW esc_set_vmode ;1 6m m-mode: + ; C 0 - 40x25 cursor on + ; M 1,2 - 64x25 cursor on + ; M 3 - 80x25 cursor on + ; C 4 - 40x25 cursor off + ; M 5,6 - 64x25 cursor off + ; M 7 - 80x25 cursor off + ; M 8 - 20rows mode + ; 9 - cursor off + ; 10 - cursor on + DW esc_set_charset ;1 7n where n is: + ; 0 - LAT Both cases + ; 1 - RUS Both cases + ; 2 - LAT+RUS Upper case + DW esc_set_palette ;1 8c c - Foreground+Backgound + DW esc_set_cursor2 ;2 9xy + DW esc_print_screen ;1 : + DW esc_draw_circle ;5 ;xyraxay X,Y, Radius, aspect ratio X, aspect ratio Y + DW esc_paint ;5 = + DW esc_picture ;6 > + DW esc_set_beep ;4 ?ppdd pp-period (word), dd - duration (word) + +esc_set_beep: + ; param byte 1+2 -> period + LD DE, M_VARS.esc_param + LD A, (DE) + LD H, A + INC DE + LD A, (DE) + LD L, A + LD (M_VARS.beep_period), HL + ; param byte 3+4 -> duration + INC DE + LD A, (DE) + LD H, A + INC DE + LD A, (DE) + LD L, A + LD (M_VARS.beep_duration), HL + RET + +esc_set_cursor2: + JP esc_set_cursor + +esc_print_screen: + LD A, (M_VARS.screen_mode) + AND 00000011b + RET NZ ; ret if not 0-3 mode + LD DE, 0x30ff + CALL m_print_hor_line + DEC E + LD D, 0xf0 + +.chk_keys: + CALL m_con_status + OR A + JP Z, .no_keys + CALL m_con_in + CP ASCII_ESC + RET Z + +.no_keys: + CALL m_print_hor_line + DEC E + JP NZ, .chk_keys + LD D, 0xe0 ; 224d + CALL m_print_hor_line + RET + +; ------------------------------------------------------ +; Print line to printer +; D - width +; ------------------------------------------------------ +m_print_hor_line: + LD HL, cmd_esc_set_X0 + + ; Set printer X coordinate = 0 + CALL m_print_cmd + LD HL, 4 + LD (M_VARS.ul_var0), HL ; Set start coord X = 4 + LD B, 0x0 ; TODO: LD B, H (save 1b 3t) + +.print_next_col: + LD C, 0x0 + ; 1 + CALL m_get_7vpix + AND D + CALL NZ, m_print_vert_7pix + LD HL, (M_VARS.ul_var0) + INC HL + + ; inc X + LD (M_VARS.ul_var0), HL + LD C, 0x1 + ; 2 + CALL m_get_7vpix + AND D + CALL NZ, m_print_vert_7pix + LD HL, (M_VARS.ul_var0) + INC HL + ; inc X + LD (M_VARS.ul_var0), HL + INC B + LD A, B + CP 236 + JP C, .print_next_col + LD HL, cmd_esc_inc_Y2 + CALL m_print_cmd + RET + +; ------------------------------------------------------ +; Send command to printer +; Inp: HL -> command bytes array +; ------------------------------------------------------ +m_print_cmd: + PUSH BC +.print_nxt: + LD A, (HL) + CP ESC_CMD_END + JP Z, .cmd_end + LD C, A + CALL m_char_print + INC HL + JP .print_nxt +.cmd_end: + POP BC + RET + +; ------------------------------------------------------ +; Print 7 vertical pixels to printer +; Inp: A - value to print +; ------------------------------------------------------ +m_print_vert_7pix: + PUSH AF + ; Set coordinate X to 0 + LD HL, cmd_esc_set_X + CALL m_print_cmd + LD HL, (M_VARS.ul_var0) + LD C,H + CALL m_char_print + LD C,L + CALL m_char_print + ; Set column print mode + LD HL, cmd_esc_print_col + CALL m_print_cmd + POP AF + ; Print 7 vertical pixels + LD C, A + CALL m_char_print + RET + +; ------------------------------------------------------ +; Control codes for printer УВВПЧ-30-004 +; ------------------------------------------------------ +; Zn - Increment Y coordinate +; 0xe2a5 +cmd_esc_inc_Y2: + DB ASCII_ESC + DB 'Z' + DB 2h + DB ESC_CMD_END + +; Xnn - Set X coordinate +cmd_esc_set_X0: + DB ASCII_ESC + DB 'X' + DB 0h ; 0..479 + DB 0h + DB ESC_CMD_END + +; ------------------------------------------------------ +; X - Start on "Set X coordinate" command +; ------------------------------------------------------ +cmd_esc_set_X: + DB ASCII_ESC + DB 'X' + DB ESC_CMD_END + +; O - Column print (vertical 7 bit) +cmd_esc_print_col: + DB ASCII_ESC + DB 'O' + DB ESC_CMD_END + +; ------------------------------------------------------ +; Get 7 vertical pixels from screen +; Inp: C - sheet +; Out: A - byte +; ------------------------------------------------------ +m_get_7vpix: + LD A, (M_VARS.row_shift) + ADD A, B + ADD A, 19 ; skip first 20pix + LD L, A + PUSH DE + PUSH BC + LD A, E + +.calc_pix_no: + AND 0x7 + LD B, A + LD A, E + ; calc hi addr + RRA ; /8 + RRA + RRA + AND 0x1f + ADD A, A ; *2 + ADD A, 64 ; bytes per row + LD H, A + ; select sheet 0|1 + LD A, C + AND 0x1 + ADD A, H + LD H, A + ; HL = pix addr, turn on VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + LD E, (HL) ; read pixel + INC H ; HL += 512 + INC H + LD D, (HL) ; read pixel row+1 + + ; turn off VRAM access + ;v8 XOR A + LD A, 0 + OUT (SYS_DD17PB), A +.for_all_pix: + DEC B + JP M, .all_shifted + ; shift pixels D >> [CF] >> E + LD A, D + RRA + LD D, A + LD A, E + RRA + LD E, A + JP .for_all_pix +.all_shifted: + LD A, E + LD D, 0 + RRA + JP NC,.not_1_1 + LD D,00110000b +.not_1_1: + RRA + JP NC, .not_1_2 + LD A, D + OR 11000000b + LD D, A +.not_1_2: + LD A, D + POP BC + POP DE + RET + +esc_set_palette: + LD A, (M_VARS.esc_param) + AND 00111111b ; bgcol[2,1,0],pal[2,1,0] + LD (M_VARS.cur_palette), A + LD B, A + LD A, (M_VARS.screen_mode) + AND 00000011b + LD A, 0x0 + JP NZ, esp_no_colr + LD A, 0x40 + +esp_no_colr: + OR B + OUT (VID_DD67PB), A + RET + +esc_set_charset: + LD A, (M_VARS.esc_param) + AND 0x3 ; charset 0..3 + LD (M_VARS.codepage), A + RET + +; ------------------------------------------------------ +; Get address for draw symbol glyph +; Inp: A - ascii code +; Out: HL -> glyph offset +; ------------------------------------------------------ +m_get_glyph: + LD L, A ; L = ascii code + LD E, A ; E = ascii code + XOR A + LD D, A + LD H, A + ; HL = DE = ascii code + ADD HL, HL + ADD HL, DE + ADD HL, HL + ADD HL, DE + ; HL = A * 7 + LD A, E ; A = A at proc entry + CP '@' + ; First 64 symbols is same for all codepages + JP M, .cp_common + LD A, (M_VARS.codepage) + OR A + ; cp=0 - Latin letters + JP Z, .cp_common + DEC A + ; cp=1 - Russian letters + JP Z, .cp_rus + ; cp=2 - 0x40..0x5F - displayed as Lat + ; 0x60 - 0x7F - displayed as Rus + LD A, E + CP 0x60 + JP M, .cp_common +.cp_rus: + LD DE, 448 ; +448=64*7 Offset for cp1 + ADD HL, DE + +.cp_common: + LD DE, m_font_cp0-224 ; m_font_cp0-32*7 + ADD HL, DE ; add symbol glyph offset + RET + + +; -------------------------------------------------- +; Console output +; Inp: C - char +; -------------------------------------------------- +m_print_no_esc: + LD A, C + AND 0x7f ; C = 0..127 ASCII code + CP ASCII_SP ; C < ' '? + JP M, m_handle_esc_code ; jump if less + CALL m_get_glyph + EX DE, HL + LD A, (M_VARS.screen_mode) + AND 0x3 + JP NZ, mp_mode_64 ; jump to non color modes + + CALL calc_addr_40 + INC L + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + DEC H + DEC H + ; one or two bytes + LD A, B + OR B + JP Z, .l1 + DEC B + JP Z, .l2 + DEC B + JP Z, .l3 + JP .l4 +.l1: + INC H + INC H + LD BC, 0xffc0 + LD A, 0x0 + JP .l5 +.l2: + LD BC, 0xf03f + LD A, 0x6 + JP .l5 +.l3: + LD BC, 0xfc0f + LD A, 0x4 + JP .l5 +.l4: + LD BC, 0xff03 + LD A, 0x2 +.l5: + LD (M_VARS.esc_var1), A + EX DE, HL + +.sym_draw: + LD A, (M_VARS.esc_var1) + PUSH HL + LD L, (HL) + LD H, 0x0 + OR A + JP Z, .pne_l8 + +.pne_l7: + ADD HL, HL + DEC A + JP NZ, .pne_l7 + +.pne_l8: + EX DE, HL + LD A, (HL) + AND C + LD (HL), A + LD A, (M_VARS.curr_color) + AND E + OR (HL) + LD (HL), A + INC H + LD A, (HL) + AND C + LD (HL), A + LD A, (M_VARS.curr_color+1) + AND E + OR (HL) + LD (HL), A + INC H + LD A, (HL) + AND B + LD (HL), A + LD A, (M_VARS.curr_color) + AND D + OR (HL) + LD (HL), A + INC H + LD A, (HL) + AND B + LD (HL), A + LD A, (M_VARS.curr_color+1) + AND D + OR (HL) + LD (HL), A + INC L + DEC H + DEC H + DEC H + EX DE, HL + POP HL + INC HL + LD A, (M_VARS.esc_var0) + DEC A + LD (M_VARS.esc_var0), A + JP NZ, .sym_draw + + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + + ; draw cursor on return + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_rt: + INC HL + LD A, (HL) ; a = col + ADD A, 1 ; col+1 + AND 0x3f ; screen column 0..63 + LD (HL), A ; save new col + CP 40 + DEC HL + RET M ; Return if no wrap + +m40_wrap_rt: + INC HL + XOR A + LD (HL), A + DEC HL + LD A, (M_VARS.screen_mode) + AND 0x08 ; screen_mode=8? + JP NZ, m2_lf + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_lf: + LD A, (HL) + ADD A, 10 + CP 248 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_bksp: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A + AND 0x3f ; A=0..63 + CP 0x3f + JP Z, .wrap + LD (HL), A + DEC HL + RET + +.wrap: + LD A, 39 + LD (HL), A + DEC HL + ; and cursor up + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_up: + LD A, (HL) + SUB 10 ; 10 rows per symbol + JP NC, .up_no_minus + LD A, 240 ; wrap to bottom +.up_no_minus: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor right 8 pos) 20rows mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m20_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x3f ; wrap A=0..63 + LD (HL), A + CP 40 + DEC HL + RET M ; ret if column <40 + JP m40_wrap_rt ; or wrap to next line + +; -------------------------------------------------- +; Calculate VRAM address in 40 column mode +; -------------------------------------------------- +calc_addr_40: + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + CP 4 + LD B, A + JP M, .l2 + AND 0x3 + LD B, A + LD A, H + OR A + RRA + OR A + RRA + LD C, A + LD H, 0x6 + XOR A + +.l1: + ADD A, H + DEC C + JP NZ, .l1 + ADD A, B + +.l2: + ADD A, B + ADD A, 66 + LD H, A + LD A, 0x7 + LD (M_VARS.esc_var0),A + RET + +m2_lf: + LD A, (HL) + ADD A, 10 + CP 15 + JP NC, .lf_nowr + LD (HL), A + RET + +.lf_nowr: + LD A, (M_VARS.row_shift) + LD L, A + ADD A, ASCII_LF + LD E, A + LD C, ASCII_BS + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.cas_l5: + LD B, 0x40 + LD H, 0x40 ; TODO: LD H, B save 1b 3t + LD D, H + +.cas_l6: + LD A, (DE) + LD (HL), A + INC H + INC D + DEC B + JP NZ, .cas_l6 + INC L + INC E + DEC C + JP NZ, .cas_l5 + LD C, 10 + LD A, (M_VARS.row_shift) + ADD A, 8 + LD E, A + +.cas_l7: + LD B, 0x40 + LD D, 0x40 ; TODO: LD D, B save 1b 3t + XOR A + +.cas_l8: + LD (DE),A + INC D + DEC B + JP NZ,.cas_l8 + INC E + DEC C + JP NZ,.cas_l7 + LD A,0x0 + OUT (SYS_DD17PB),A + RET + + +; --------------------------------------------------- +; Handle ASCII_BS (cursor left) in 20row mode +; --------------------------------------------------- +m20_bksp: + INC HL + LD A, (HL) + OR A + DEC HL + RET Z + + INC HL + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x3f + LD (HL), A + DEC HL + RET + +; --------------------------------------------------- +; Print symbol in 64x25 mode +; --------------------------------------------------- +mp_mode_64: + CP 3 ; + JP Z, mp_mode_80 ; jump for screen_mode=3 + ; calc symbol address in VRAM + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + ADD A, 0x40 + LD H, A + ; + LD C, 7 ; symbol height + + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + EX DE, HL + XOR A + LD (DE), A + INC E + +.next_row: + LD A, (HL) + ADD A, A + LD (DE), A + INC HL + INC E + DEC C + JP NZ, .next_row + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + ; draw cursor at end + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_rt: + INC HL + LD A, (HL) + ADD A, 1 + AND 0x3f ; wrap + LD (HL), A + DEC HL + RET NZ ; ret if no wrap + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_lf: + LD A, (HL) + ADD A, 10 + CP 248 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Scroll Up for 10 rows +; -------------------------------------------------- +scroll_up: + LD A, (M_VARS.row_shift) + ADD A, 10 + OUT (SYS_DD17PA), A ; Scroll via VShift register + LD (M_VARS.row_shift), A ; store new VShift value + ; calc bottom 16 rows address in VRAM + LD HL, 0x40f0 ; 240th VRAM byte + ADD A, L + LD L, A + LD C, H + + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + XOR A + LD DE, 0x1040 ; D=16 E=64 (512/8 bytes in row) + +.next_row: + LD H, C + LD B, E + + ; clear 64 bytes (512px in mono or 256px in color mode) +.next_col: + LD (HL), A + INC H ; next column + DEC B + JP NZ, .next_col + INC L ; next row address + DEC D ; row counter - 1 + JP NZ, .next_row + + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_bs: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x3f ; wrap column (0..63) + LD (HL), A + CP 63 + DEC HL + RET NZ + ; cursor up if wrapped + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_up: + LD A, (HL) + SUB 10 + JP NC, .no_wrap + LD A, 240 + +.no_wrap: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor column + 8) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x38 + LD (HL), A + DEC HL + RET NZ ; return if no wrap + ; cursor down if wrap + JP m64_lf + +; -------------------------------------------------- +; Print symbols in 80x25 mode +; -------------------------------------------------- +mp_mode_80: + CALL calc_addr_80 + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + ; fix address + EX DE, HL + INC E + ; make bitmask + LD A, B + OR A + JP Z, .l1 + DEC A + JP Z, .l2 + DEC A + JP Z, .l3 + JP .l4 + +.l1: + LD B, (HL) + LD A, (DE) + AND 0xc0 + OR B + LD (DE), A + INC HL + INC E + DEC C + JP NZ, .l1 + JP .l6 +.l2: + LD A, (HL) + RRCA + RRCA + AND 0x7 + LD B, A + LD A, (DE) + AND 0xf0 + OR B + LD (DE), A + LD A, (HL) + RRCA + RRCA + AND 0xc0 + LD B, A + DEC D + LD A, (DE) + AND 0x1f + OR B + LD (DE), A + INC D + INC HL + INC E + DEC C + JP NZ, .l2 + JP .l6 +.l3: + LD A, (HL) + RRCA + RRCA + RRCA + RRCA + AND 0x1 + LD B, A + LD A, (DE) + AND 0xfc + OR B + LD (DE), A + LD A, (HL) + RRCA + RRCA + RRCA + RRCA + AND 0xf0 + LD B, A + DEC D + LD A, (DE) + AND 0x7 + OR B + LD (DE), A + INC D + INC HL + INC E + DEC C + JP NZ, .l3 + JP .l6 +.l4: + DEC D +.l5: + LD A, (HL) + RLCA + RLCA + LD B, A + LD A, (DE) + AND 0x1 + OR B + LD (DE), A + INC HL + INC E + DEC C + JP NZ, .l5 + INC D + +.l6: + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + ; Draw cursor after symbol + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_rt: + INC HL + LD A, (HL) + ADD A, 1 ; inc column + AND 0x7f + LD (HL), A + CP 80 + DEC HL + RET M ; return if no wrap + +m80_col_wrap: + INC HL + XOR A + LD (HL), A + DEC HL + ; and move cursor to next row + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_lf: + LD A, (HL) + ADD A, 10 + CP 248 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_bs: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x7f ; mask [0..127] + CP 127 + JP Z, .wrap + LD (HL), A + DEC HL + RET + +.wrap: + LD A, 79 + LD (HL), A + DEC HL + ; and move cursor to previous line + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_up: + LD A, (HL) + SUB 10 + JP NC, .no_wrap + LD A, 240 + +.no_wrap: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor column + 8) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x7f + LD (HL), A + CP 80 + DEC HL + RET M ; return if no cursor wrap + JP m80_col_wrap + +; -------------------------------------------------- +; Calculate address for cursor pos for 80x25 mode +; Out: HL -> VRAM +; B -> pixel pos in byte +; -------------------------------------------------- +calc_addr_80: + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + CP 4 + LD B, A + JP M, mns_ep_fm_0 + AND 3 + LD B, A + LD A, H + OR A + RRA + OR A + RRA + LD C, A + LD H, 3 + XOR A +mns_l1: + ADD A, H + DEC C + JP NZ, mns_l1 + ADD A, B +mns_ep_fm_0: + ADD A, 0x42 + LD H, A + LD C, 0x7 + RET + +; -------------------------------------------------- +; Clear screen and set cursor to 0,0 +; Inp: HL -> cursor position +; -------------------------------------------------- +m_clear_screen: + LD A, (M_VARS.screen_mode) + AND 0x8 + JP NZ, m_clear_20_rows ; for bit 4 is set, clear only 20 rows + ; all in black + LD A, 01111111b + OUT (VID_DD67PB), A ; C/M=1 FL=111 CL=111 All black + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + LD DE, video_ram + EX DE, HL + LD A, H + ADD A, 0x40 ; A=0x80 + LD B, 0 + +.fill_scrn: + LD (HL), B + INC HL + CP H + JP NZ, .fill_scrn ; fill while HL<0x8000 + + EX DE, HL + LD A, (M_VARS.cur_palette) + LD B, A ; B = current palette + LD A, (M_VARS.screen_mode) + AND 0x3 ; color? + LD A, 0x0 + JP NZ, .mono_mode + LD A, 01000000b +.mono_mode: + OR B + ; Restore mode and palette + OUT (VID_DD67PB), A + + ; And set cursor to home position + +; -------------------------------------------------- +; Set cursor to 0,0 and close VRAM access +; Inp: HL -> cursor_row +; -------------------------------------------------- +m_cursor_home: + XOR A + NOP + NOP + LD (HL), A + INC HL + XOR A + LD (HL), A + DEC HL + ;XOR A + LD A, 0 + ; Disable VRAM access + OUT (SYS_DD17PB), A + RET + +; Clear only 20 rows +m_clear_20_rows: + ; take row shift in account + LD A, (M_VARS.row_shift) + LD L, A + LD C, 20 + + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.next_row: + LD H, 0x40 ; HL = 0x4000 + shift_row + LD B, 64 ; 64 bytes at row + XOR A +.next_col: + LD (HL), A + INC H ; next column + DEC B + JP NZ, .next_col + INC L ; next row + DEC C + JP NZ, .next_row + ; Disabe VRAM access + LD A, 0 + OUT (SYS_DD17PB), A + JP m_cursor_home + +; -------------------------------------------------- +; Draw cursor at current cursor position +; if not hidden +; -------------------------------------------------- +m_draw_cursor: + LD A, (M_VARS.screen_mode) + AND 0x4 ; check hidden cursor bit + RET NZ ; return if hidden + LD A, (M_VARS.screen_mode) + AND 0x3 ; check color mode (40 column mode 6x7 font) + JP NZ, .dc_mode_64 + + EX DE, HL + LD HL, (M_VARS.cursor_row) + LD A, H ; cursor column + CP 40 ; > 40? + EX DE, HL + RET P ; ret if column out of screen + + PUSH HL + EX DE, HL + CALL calc_addr_40 + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; previous address + DEC H + DEC H + INC L + LD C, 7 ; cursor size + ; build masks + LD A, B + OR B + JP Z, .dc_rt2 + DEC B + JP Z, .dc_mid + DEC B + JP Z, .dc_lt + JP .dc_rt1 +.dc_rt2: + INC H + INC H + LD DE, 0x001f + JP .dc_put +.dc_mid: + LD DE, 0x07c0 + JP .dc_put +.dc_lt: + LD DE, 0x01f0 + JP .dc_put +.dc_rt1: + LD DE, 0x007c + +.dc_put: + ; xor cursor mask with VRAM[HL] value + ; left bytes + LD A, (HL) + XOR E + LD (HL), A + INC H + LD A, (HL) + XOR E + LD (HL), A + ; right bytes + INC H + LD A, (HL) + XOR D + LD (HL), A + INC H + LD A, (HL) + XOR D + LD (HL), A + ; next cursor row address + INC L + DEC H + DEC H + DEC H + DEC C + JP NZ, .dc_put ; draw next cursor row if c>0 + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + POP HL + RET + + ; draw cursor in 64 column mode +.dc_mode_64: + CP 3 ; screen_mode = 3 - 80 rows + JP Z, .dc_mode_80 + EX DE, HL + LD HL, (M_VARS.cursor_row) ; H - col, L - row + ; take into account the vertical shift + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + ; + LD A, H + CP 64 ; check column + EX DE, HL + RET P ; return if column out of screen + EX DE, HL + ; calc VRAM address + ADD A, 0x40 + LD H, A + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + LD BC, 0x7f08 ; B=01111111b - mask, C=8 - cursor size +.cur_64_next: + ; xor with VRAM content + LD A, (HL) + XOR B + LD (HL), A + ; next row address + INC L + DEC C + JP NZ, .cur_64_next + EX DE, HL + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + + ; draw cursor in 80 column mode +.dc_mode_80 + EX DE, HL + LD HL, (M_VARS.cursor_row) + + LD A, H + CP 80 + EX DE, HL + RET P ; return if column > 80 + + PUSH HL + CALL calc_addr_80 + LD C, 7 ; cursor size + INC L + + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; mask + LD A, B + OR A + LD B, 0x1f + JP Z, .dc_1_byte + DEC A + LD DE, 0xc007 + JP Z, .dc_2_byte + DEC A + LD DE, 0xf001 + JP Z, .dc_2_byte + LD B, 0x7c + DEC H + JP .dc_1_byte ; TODO: unused + +.dc_1_byte: + ; xor with VRAM byte + LD A, (HL) + XOR B + LD (HL), A + INC L + DEC C + JP NZ, .dc_1_byte + JP .dc_80_end + +.dc_2_byte: + ; xor with previous byte + DEC H + LD A, (HL) + XOR D + LD (HL), A + ; xor with current byte + INC H + LD A, (HL) + XOR E + LD (HL), A + ; next cursor address + INC L + DEC C + JP NZ, .dc_2_byte + +.dc_80_end: + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + POP HL + RET + +; -------------------------------------------------- +; If ESC character, turn esc_mode ON +; Inp: A - ASCII symbol +; -------------------------------------------------- +m_handle_esc_code: + CP ASCII_ESC + JP NZ, m_handle_control_code + ; turn on ESC mode for next chars + LD HL, M_VARS.esc_mode + LD (HL), 0x1 ; turn on ESC mode + INC HL + LD (HL), 0xff ; esc_cmd = 0xff + RET + +; -------------------------------------------------- +; Handle one byte ASCII control code +; Inp: A - ASCII symbol +; -------------------------------------------------- +m_handle_control_code: + CP ASCII_BELL + JP Z, m_beep + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + PUSH AF + CALL m_draw_cursor + LD A, (M_VARS.screen_mode) + AND 0x08 ; 20-rows mode? + JP Z, handle_cc_common ; jump for normal screen modes + + ; for hidden cursor modes + POP AF + CP ASCII_TAB ; TAB + JP Z, m20_tab + CP ASCII_BS ; BKSP + JP Z, m20_bksp + CP ASCII_CAN ; Cancel + JP Z, m40_rt + CP ASCII_US ; ASCII Unit separator + JP Z, m_clear_20_rows + CP ASCII_LF ; LF + JP Z, m2_lf + CP ASCII_CR ; CR + RET NZ ; ret on unknown + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; Handle cursor for 40x25, 64x25, 80x25 modes +; -------------------------------------------------- +handle_cc_common: + POP AF + CP ASCII_US + JP Z, m_clear_screen + CP ASCII_FF + JP Z, m_cursor_home + PUSH AF + LD A, (M_VARS.screen_mode) + AND 3 ; check for color modes + JP NZ, .handle_cc_mono + ; 32x25 text mode + POP AF + CP ASCII_TAB ; cursor right +8 + JP Z, m20_tab + CP ASCII_BS ; cursor left + JP Z, m40_bksp + CP ASCII_CAN ; cursor right + JP Z, m40_rt + CP ASCII_EM ; cursor up + JP Z, m40_up + CP ASCII_SUB + JP Z, m40_lf ; cursor down + CP ASCII_LF + JP Z, m40_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 ; move cursor to first column for CR + DEC HL + RET + +; -------------------------------------------------- +; Handle control chars for 64x25 or 80x25 modes +; -------------------------------------------------- +.handle_cc_mono: + LD A, (M_VARS.screen_mode) + CP 3 + JP Z, handle_cc_80x25 + CP 7 + JP Z, handle_cc_80x25 + ; 64x25 screen mode + POP AF + CP ASCII_TAB + JP Z, m64_tab + CP ASCII_BS + JP Z, m64_bs + CP ASCII_CAN + JP Z, m64_rt + CP ASCII_EM + JP Z, m64_up + CP ASCII_SUB + JP Z, m64_lf + CP ASCII_LF + JP Z, m64_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; Handle control chars for 80x25 modes +; -------------------------------------------------- +handle_cc_80x25: + POP AF + CP ASCII_TAB + JP Z, m80_tab + CP ASCII_BS + JP Z, m80_bs + CP ASCII_CAN + JP Z, m80_rt + CP ASCII_EM + JP Z, m80_up + CP ASCII_SUB + JP Z, m80_lf + CP ASCII_LF + JP Z, m80_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +m_beep: + LD HL, (M_VARS.beep_duration) + EX DE, HL + LD HL, (M_VARS.beep_period) + LD A, 00110110b ; TMR#0 LSB+MSB Square Wave Generator + OUT (TMR_DD70CTR), A + LD A, L ; LSB + OUT (TMR_DD70C1), A + LD A, H ; MSB + OUT (TMR_DD70C1), A + LD A, (M_VARS.strobe_state) + LD B, A +m_bell_cont: + LD A, D ; DE=duration + OR E + RET Z ; ret if enough + DEC DE + LD A, B + XOR BELL_PIN + LD B, A + OUT (DD67PC), A ; Invert bell pin +m_bell_wait_tmr1: + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; 0x10 + JP NZ, m_bell_wait_tmr1 + LD A, B + XOR BELL_PIN ; Flip pin again + LD B, A + OUT (DD67PC), A +m_bell_wait_tmr2: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP Z,m_bell_wait_tmr2 + JP m_bell_cont + + +; ------------------------------------------------------ +; 5 Set cursor position +; ------------------------------------------------------ +esc_set_cursor: + CALL m_draw_cursor + LD DE, M_VARS.esc_param + LD HL, M_VARS.cursor_col + INC DE + LD A, (DE) ; column + SUB 32 + LD B, A + LD A, (M_VARS.screen_mode) + CP 3 + JP Z, .mode_80 + CP 7 + JP Z, .mode_80 + OR A + JP Z, .mode_40 + CP 4 + JP Z, .mode_40 + ; mode 64x25 + LD A, B + CP 64 + JP M, .common + LD A, 64 + JP .common + ; mode 40x25 +.mode_40: + LD A, B + CP 40 + JP M, .common + LD A, 40 + JP .common + ; mode 80x25 +.mode_80: + LD A, B + CP 80 + JP M, .common + LD A, 80 +.common: + LD (HL), A + DEC DE + DEC HL + LD A, (DE) + SUB 32 + CP 24 + JP C, esc_le_24 + LD A, 24 +esc_le_24: + LD B, A + ADD A, A + ADD A, A + ADD A, B + ADD A, A + LD (HL), A + CALL m_draw_cursor ; TODO change call+ret to jp + RET ; + +; ------------------------------------------------------ +; 6n Set video mode or cursor visibility +; Inp: n is +; 0 - C 32x25 with cursor; 0000 +; 1 - M 64x25 with cursor; 0001 +; 2 - M 64x25 with cursor; 0010 +; 3 - M 80x25 with cursor; 0011 +; 4 - C 32x25 no cursor; 0100 +; 5 - M 64x25 no cursor; 0101 +; 6 - M 64x25 no cursor; 0110 +; 7 - M 80x25 no cursor; 0111 +; 8 - M 20rows mode 1000 +; 9 - hide cursor 1001 +; 10 - show cursor 1010 +; ------------------------------------------------------ +esc_set_vmode: + LD HL, M_VARS.screen_mode + LD A, (M_VARS.cur_palette) + LD B, A + LD A, (M_VARS.esc_param) ; first parameter - video mode + AND 0xf + CP 11 + RET NC ; return if not valid input parameter + CP 9 + JP Z, .cursor_hide + CP 10 + JP Z, .cursor_show + LD (HL), A ; store new mode + CP 4 + JP Z, .set_color_mode + AND 0x3 ; monochrome (80x25, 64x25) mode? + LD A, 0 ; mode 512x254 mono + JP NZ, .skip_for_mono_mode + ; mode=0 or 4 -> 256x256px color +.set_color_mode: + LD A, 0x40 ; color mode +.skip_for_mono_mode: + OR B ; color mode with palette + OUT (VID_DD67PB), A ; configure screen mode + + LD HL, M_VARS.cursor_row + CALL m_clear_screen + +.draw_cursor: + CALL m_draw_cursor ; TODO change call+ret to jp + RET + +.cursor_hide: + LD A, (HL) ; screen_mode + OR 00000100b ; cursor hide + LD (HL), A + LD HL, M_VARS.cursor_row + JP .draw_cursor + +.cursor_show: + LD A, (HL) ; screen_mode + AND 11111011b ; cursor show + LD (HL), A + JP .draw_cursor + + +; ------------------------------------------------------ +; 4n n=1..4 Set drawing color +; ------------------------------------------------------ +esc_set_color: + LD A, (M_VARS.esc_param) +m_set_color: + AND 0x3 + RRA + LD B, A + LD A, 0x0 ; TODO: unused + SBC A, A + LD (M_VARS.curr_color), A + LD A, B + DEC A + CPL + LD (M_VARS.curr_color+1), A + RET + +;--------------------------------------------------- +; Print symbol or print sprite at X,Y coordinates +; Inp: param x,y +; C - character or sprite_no to draw +;--------------------------------------------------- +m_print_at_xy: + ; check video mode + LD A, (M_VARS.screen_mode) + AND 0x3 ; color? + JP NZ, esc_exit ; exit for mono modes + + LD A, C + AND 0x7f + LD C, A ; C = C with 7th bit reset + CP 0x1 + JP Z, .sprites_en ; enable sprite mode + + CP ASCII_SP + JP M, mode2_exit ; codes 0..31 - turm off game_mode + + ; check X, Y range to prevent drawing symbols out of screen + LD HL, M_VARS.esc_param + LD A, (HL) + LD E, A + ADD A, 8 + JP C, mode2_exit ; exit if esc_param[0]>247 + LD (HL), A + INC HL ; HL -> esc_param[1] + LD A, 247 + CP (HL) + JP C, mode2_exit ; exit if esc_param[1]>247 + ; calculate X,Y pixel address in VRAN + LD D, (HL) + CALL calc_px_addr + ; HL - address, B - pixel pos in byte + LD A, L + SUB 8 + LD L, A + PUSH HL ; save address + + LD A, (M_VARS.esc_var2) + OR A + JP NZ, .mode_sp + + ; font + LD A, C + CALL m_get_glyph + LD C, 7 + POP DE + INC E + JP .out_sp + + ; sprite mode +.mode_sp: + LD A, C + SUB 32 + CP 35 + JP NC, co_ex_l08 + + ; Calc sprite address + LD L, A ; HL=A - sprite_no + XOR A + LD H, A + ADD HL, HL + ADD HL, HL + ADD HL, HL ; HL=HL*8 + LD DE, game_sprite_tab + ADD HL, DE ; HL -> sprite + LD C, 8 ; bytes count + POP DE + + ; Out sprite + ; DE -> VRAM address + ; C - height +.out_sp: + LD A, (M_VARS.esc_param+2) + DEC A + JP Z, out_no_xor + +.next_line: + PUSH HL + ; Access Video RAM + LD A, 0x1 + OUT (SYS_DD17PB), A + LD L, (HL) ; load from table + LD H, 0x0 + LD A, B + OR A + JP Z, .l05 +.l04: + ADD HL, HL + DEC A + JP NZ, .l04 +.l05: + EX DE, HL + LD A, (M_VARS.curr_color) + AND E + XOR (HL) + LD (HL), A + INC H + INC H + LD A, (M_VARS.curr_color) + AND D + XOR (HL) + LD (HL), A + DEC H + LD A, (M_VARS.curr_color+1) + AND E + XOR (HL) + LD (HL), A + INC H + INC H + LD A, (M_VARS.curr_color+1) + AND D + XOR (HL) + LD (HL), A + DEC H + DEC H + DEC H + INC L + EX DE, HL + ; Disable VRAM + LD A, 0x0 + OUT (SYS_DD17PB), A + POP HL + INC HL + DEC C + JP NZ, .next_line + RET + +.sprites_en: + LD (M_VARS.esc_var2), A + RET + +mode2_exit: + XOR A + LD (M_VARS.esc_var2), A + JP esc_exit + +co_ex_l08: + POP DE + JP mode2_exit + +out_no_xor: + PUSH HL + ; Acess to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + LD L, (HL) + LD H, 0x0 + LD A, B + OR A + JP Z, .l11 +.l10: + ADD HL, HL + DEC A + JP NZ, .l10 +.l11: + EX DE, HL + PUSH BC + LD A, (M_VARS.curr_color) + CPL + LD B, A + LD A, (HL) + XOR B + OR E + XOR B + LD (HL), A + INC H + INC H + LD A, (HL) + XOR B + OR D + XOR B + LD (HL), A + DEC H + LD A, (M_VARS.curr_color+1) + CPL + LD B, A + LD A, (HL) + XOR B + OR E + XOR B + LD (HL), A + INC H + INC H + LD A, (HL) + XOR B + OR D + XOR B + LD (HL), A + DEC H + DEC H + DEC H + INC L + EX DE, HL + POP BC + + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + + POP HL + INC HL + DEC C + JP NZ, out_no_xor + RET + +game_sprite_tab: + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; 0x00 + DB 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E ; 0x01 + DB 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E ; 0x02 + DB 0x00, 0x08, 0x08, 0x14, 0x63, 0x14, 0x08, 0x08 ; 0x03 + DB 0x36, 0x7F, 0x7F, 0x7F, 0x3E, 0x1C, 0x08, 0x00 ; 0x04 + DB 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00 ; 0x05 + DB 0x1C, 0x3E, 0x1C, 0x7F, 0x7F, 0x6B, 0x08, 0x1C ; 0x06 + DB 0x08, 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x08, 0x1C ; 0x07 + DB 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18 ; 0x08 + DB 0x18, 0xDB, 0x3C, 0xE7, 0xE7, 0x3C, 0xDB, 0x18 ; 0x09 + DB 0xE7, 0xE7, 0x00, 0x7E, 0x7E, 0x00, 0xE7, 0xE7 ; 0x0a + DB 0x7E, 0x81, 0x81, 0xFF, 0xFF, 0x81, 0x81, 0x7E ; 0x0b + DB 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18 ; 0x0c + DB 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00 ; 0x0d + DB 0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00 ; 0x0e + DB 0x00, 0x08, 0x0C, 0xFE, 0xFE, 0x0C, 0x08, 0x00 ; 0x0f + DB 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 ; 0x10 + DB 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 ; 0x11 + DB 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0 ; 0x12 + DB 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F ; 0x13 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; 0x14 + DB 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ; 0x15 + DB 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F ; 0x16 + DB 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 ; 0x17 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ; 0x18 + DB 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 ; 0x19 + DB 0x70, 0x08, 0x76, 0xFF, 0xFF, 0xFF, 0x7E, 0x18 ; 0x1a + DB 0xC3, 0xDB, 0xDB, 0x18, 0x18, 0xDB, 0xDB, 0xC3 ; 0x1b + DB 0xFC, 0xCC, 0xFC, 0x0C, 0x0C, 0x0E, 0x0F, 0x07 ; 0x1c + DB 0xFE, 0xC6, 0xFE, 0xC6, 0xC6, 0xE6, 0x67, 0x03 ; 0x1d + DB 0x18, 0x3C, 0x3C, 0x18, 0x7E, 0x18, 0x24, 0x66 ; 0x1e + DB 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 ; 0x1f + DB 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 ; 0x20 + DB 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 ; 0x21 + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF ; 0x22 + +; -------------------------------------------------- +; Calculate address of pixel in Video RAM +; Inp: DE - Y, X +; Out: HL - address +; B - offset in byte +; -------------------------------------------------- +calc_px_addr: + ; take into account the vertical displacement + LD A, (M_VARS.row_shift) + SUB D + DEC A + LD L, A + + LD A, E + AND 0x07 ; X mod 8 - offset in byte + LD B, A + + LD A, E + RRA + RRA + AND 00111110b + ADD A, 0x40 ; VRAM at 0x4000 + LD H, A + RET + + +;--------------------------------------------------- +; Draw filled rectanger +; Inp: esc param X1,Y2,X2,Y2 +; -------------------------------------------------- +esc_draw_fill_rect: + LD HL, M_VARS.esc_param + LD E, (HL) ; E=X1 + INC HL + LD C, (HL) ; C=Y1 + INC HL + INC HL + LD D, (HL) ; D=Y2 + LD A, D + SUB C ; delta Y + JP NZ, .non_zero_h + INC A ; 1 as minimum +.non_zero_h: + LD C, A ; C = height + ; DE = Y2, X1 + CALL calc_px_addr + ; HL -> videomem offset, b - pixel offset + + ; build pixel mask + XOR A +.shift_mask_l: + SCF + RLA + DEC B + JP P, .shift_mask_l + RRA + LD (M_VARS.pixel_mask_l), A + CPL ; invert + LD (M_VARS.pixel_mask_l_i), A + LD A, (M_VARS.esc_param+2) ; X2 + AND 0x7 ; 0..7 + LD B, A + XOR A +.shift_mask_r: + SCF + RLA + DEC B + JP P, .shift_mask_r + LD (M_VARS.pixel_mask_r_i), A + LD B, C + ; calc end address + LD A, (M_VARS.esc_param+2) ; X2 + RRA + RRA + AND 00111110b + ADD A, 0x40 + SUB H + RRCA + LD C, A ; C - width + INC B + LD A, (M_VARS.esc_param+4) + DEC A + JP NZ, .rectangle_xor + LD A, (M_VARS.pixel_mask_r_i) + CPL + LD (M_VARS.pixel_mask_r), A + LD D, A + LD A, (M_VARS.pixel_mask_l) + LD E, A + ; draw B horisontal lines +.next_line: + PUSH DE + PUSH HL + PUSH BC + CALL draw_line_h + POP BC + POP HL + POP DE + INC L + DEC B + JP NZ, .next_line + RET + + ; draw B horisontal lines (xor) +.rectangle_xor: + LD A, (M_VARS.pixel_mask_r_i) + LD (M_VARS.pixel_mask_r), A + LD D, A + LD A, (M_VARS.pixel_mask_l_i) + LD E, A + ; Access to VideoRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.edf_l6: + PUSH DE + PUSH HL + PUSH BC + LD A, C + OR A + JP NZ, .w_ne_0 ; jump if width != 0 + LD A, E ; merge masks E=E or D + OR D +.next_8px: + LD E, A +.w_ne_0: + LD B, E ; B - mask + EX DE, HL + LD HL, (M_VARS.curr_color) ; color + EX DE, HL + ; Set pixels - VideoRAM[HL] = color xor VideoRAM[HL] + LD A, E + AND B + XOR (HL) + LD (HL), A + ; And next byte + INC H + LD A, D + AND B + XOR (HL) + LD (HL), A + ; ---------- + INC H + LD A, C + OR A + JP Z, .complete + DEC C + ; right tail of line, use right mask +.r_mask: + LD A, (M_VARS.pixel_mask_r) + JP Z, .next_8px + ; full 8 bits without mask at middle of line +.next_full: + LD A, (HL) + XOR E + LD (HL), A + INC H + LD A, (HL) + XOR D + LD (HL), A + INC H + DEC C + JP NZ, .next_full + JP .r_mask +.complete: + POP BC + POP HL + POP DE + INC L + DEC B + JP NZ, .edf_l6 + ; Disable VideoRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +;--------------------------------------------------- +; Paint screen +; Inp: params X,Y,Color,repColor +;--------------------------------------------------- +esc_paint: + ; Save stack + LD HL, 0x0 + ADD HL, SP + LD (M_VARS.paint_sp_save), HL + + ; Set our own stack + LD HL, M_VARS.paint_stack ; TODO: Z80 LD SP,var i800 - LXI SP,nn + LD SP, HL + + ; save current color + LD HL, (M_VARS.curr_color) + LD (M_VARS.tmp_color), HL + + ; set color from param 3 + LD A, (M_VARS.esc_param+2) + DEC A + CALL m_set_color + + ; color to replace, from param 4 + LD A, (M_VARS.esc_param+3) + DEC A + LD (M_VARS.cmp_color), A + + ; HL - Y,X + LD A, (M_VARS.esc_param) + LD L, A + LD A, (M_VARS.esc_param+1) + LD H, A + LD (M_VARS.paint_y), A + + LD A, (M_VARS.esc_param+4) ; 0 - full fill, 1 - fast fill + DEC A + LD (M_VARS.esc_param), A + + LD A, 0x2 + LD (M_VARS.paint_var5), A ; task_no=2 + + EX DE, HL + CALL calc_px_addr + LD (M_VARS.esc_param+1), HL ; temporary ctore address of start fill point + ; make mask + LD A, 10000000b +.l1: + RLCA + DEC B + JP P, .l1 + + LD B, A + LD (M_VARS.esc_param+3), A ; store mask + + ; find left border + LD A, (M_VARS.cmp_color) + LD C, A + LD D, E ; D = X + CALL paint_find_left + ; find right border + LD HL, (M_VARS.esc_param+1) ; restore HL + LD A, (M_VARS.esc_param+3) ; restore mask + LD B, A + CALL paint_find_right + ; + LD HL, 0x0 + PUSH HL + PUSH HL + ; + LD A, (M_VARS.esc_param) ; A = fill mode + OR A + JP Z, ep_fm_0 + ; push fill task parameters + LD A, (M_VARS.paint_var5) + DEC A ; task_no-1 + LD H, A + LD L, E + PUSH HL + LD A, (M_VARS.paint_y) + LD H, A + LD L, D + PUSH HL + +ep_fm_0: + ; push fill task parameters + LD A, (M_VARS.paint_var5) ; task_no + LD H, A + LD L, E + PUSH HL + LD A, (M_VARS.paint_y) + LD H, A + LD L, D + PUSH HL + JP paint_task ; exec task + +ep_task_end: + LD A, (M_VARS.cmp_color) + LD C, A ; color to compare + + LD A, (M_VARS.esc_param) ; fill mode 0 - full, 1 - fast + OR A + JP NZ, ep_f_fast + + LD A, 0x2 + LD (M_VARS.paint_var7), A + LD A, (M_VARS.paint_var2) + CP 2 + JP Z, ep_l4 + JP ep_l5 ; TODO: change to one JP NZ + +ep_l4: + LD A, 1 + LD (M_VARS.paint_var5), A ; task_no? + JP ep_l8 + +ep_l5: + LD A, 2 + LD (M_VARS.paint_var5), A + JP ep_l11 + +ep_l6: + LD A, (M_VARS.paint_var7) + OR A + JP Z, paint_task + LD A, (M_VARS.paint_var2) + CP 2 + JP Z, ep_l5 ; TODO: change to one JP NZ + JP ep_l4 + +ep_f_fast: + LD A, (M_VARS.paint_var2) + LD (M_VARS.paint_var5), A + CP 1 ; TODO: DEC A - save 1b 3t + JP Z, ep_l8 ; TODO: change to one JP NZ + JP ep_l11 + +ep_l8: + LD A, (M_VARS.paint_var3) + LD D, A + LD A, (M_VARS.paint_var1) + LD E, A + LD HL, (M_VARS.esc_param+1) + LD A, (M_VARS.esc_param+3) + LD B, A + LD A, (M_VARS.paint_var4) + DEC A + JP Z, ep_l10 + LD (M_VARS.paint_y), A + INC L + CALL paint_find_next_right + JP Z, ep_l10 + LD HL, (M_VARS.esc_param+4) + LD A, (M_VARS.esc_param+6) + LD B, A + INC L + CALL paint_find_next_left + JP Z, ep_l10 + LD A, (M_VARS.esc_param) + OR A + JP NZ, ep_l9 + JP ep_l12 + +ep_l9: + LD A, (M_VARS.paint_var5) + LD H, A + LD L, E + PUSH HL + LD A, (M_VARS.paint_y) + LD H, A + LD L, D + PUSH HL + JP paint_task + +ep_l10: + LD A, (M_VARS.esc_param) + OR A + JP NZ, paint_task + LD A, (M_VARS.paint_var7) + DEC A + LD (M_VARS.paint_var7), A + JP ep_l6 + +ep_l11: + LD A, (M_VARS.paint_var3) + LD D, A + LD A, (M_VARS.paint_var1) + LD E, A + LD HL, (M_VARS.esc_param+1) + LD A, (M_VARS.esc_param+3) + LD B, A + LD A, (M_VARS.paint_var4) + INC A + CP 0xff + JP Z, ep_l10 + LD (M_VARS.paint_y), A + DEC L + CALL paint_find_next_right + JP Z, ep_l10 + LD HL, (M_VARS.esc_param+4) + LD A, (M_VARS.esc_param+6) + LD B, A + DEC L + CALL paint_find_next_left + JP Z, ep_l10 + LD A, (M_VARS.esc_param) + OR A + JP NZ, ep_l9 + JP ep_l12 + +; --------------------------------------------------- +; +; --------------------------------------------------- +paint_find_next_right: + CALL get_pixel + JP NZ, .l1 + CALL paint_find_left + LD A, 0xff + OR A + RET + +.l1: + LD A, D + CP E + RET Z + INC D + LD A, B + RLCA + LD B, A + JP NC, .l2 + INC H + INC H +.l2: + CALL get_pixel + JP NZ, .l1 + LD A, 0xff + OR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +paint_find_next_left: + CALL get_pixel + JP NZ, .l1 + CALL paint_find_right + LD A, 0xff + OR A + RET +.l1: + LD A, E + CP D + RET Z + DEC E + LD A, B + RRCA + LD B, A + JP NC, .l2 + DEC H + DEC H +.l2: + CALL get_pixel + JP NZ, .l1 + LD A, 0xff + OR A + RET + +ep_l12: + LD A, D + LD (M_VARS.pixel_mask_r), A + LD A, (M_VARS.paint_var5) + LD D, A + PUSH DE + LD A, (M_VARS.pixel_mask_r) + CP E + JP NZ, ep_l13 + LD L, A + LD A, (M_VARS.paint_y) + LD H, A + PUSH HL + JP ep_l16 +ep_l13: + LD D, E + CALL paint_find_left + LD E, D + LD A, (M_VARS.paint_y) + LD D, A + PUSH DE + LD A, (M_VARS.pixel_mask_r) + LD D, A + CP E + JP Z, ep_l16 +ep_l14: + DEC E + LD A, B + RRCA + LD B, A + JP NC, ep_l15 + DEC H + DEC H +ep_l15: + CALL get_pixel + JP NZ, ep_l14 + JP ep_l12 +ep_l16: + JP ep_l10 + +; --------------------------------------------------- +; Find rightmost pixel to fill +; In/Out: E = x_right +; HL - current pixel address +; B - pixel mask +; --------------------------------------------------- +paint_find_right: + LD A, E + CP 0xff + RET Z ; return if X=right border + INC E ; x=x+1 + ; rotate pixel mask right + LD A, B + RLCA + LD B, A + JP NC, .in_byte + ; inc addr+2 (2 byte per 8 pixels) + INC H + INC H + +.in_byte: + CALL get_pixel + JP Z, paint_find_right ; find until same color + ; border found, x-1 + DEC E + ; rotate mask back 1 px + LD A, B + RRCA + LD B, A + RET NC + ; addr-2 if previous byte + DEC H + DEC H + RET + +; --------------------------------------------------- +; Find leftmost pixel to fill +; In/Out: D = x_left +; HL - current pixel address +; B - pixel mask +; --------------------------------------------------- +paint_find_left: + LD A, D + OR A + RET Z ; return if x=0 + + DEC D ; x-1 + LD A, B + RRCA ; rotate mask to right + LD B, A + JP NC, .in_byte + DEC H ; addr-2 (2 byte for 8px) + DEC H + +.in_byte: + CALL get_pixel + JP Z, paint_find_left ; repeat until same color + + INC D ; border found, x+1 + ; mask rotate right + LD A, B + RLCA + LD B, A + RET NC + ; if CF, inc address+2 + INC H + INC H + RET + +; --------------------------------------------------- +; Inp: HL - address +; B - pixel mask +; C - color to compare +; Out: A - 0,1,2 +; ZF - set if color match +; --------------------------------------------------- +get_pixel: + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; get pixel and mask + LD A, (HL) + AND B + JP NZ, .bit1_set + INC H + LD A, (HL) + DEC H + AND B + JP NZ, .bit2_set + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + CP C + RET + +.bit1_set: + INC H + LD A, (HL) + DEC H + AND B + JP NZ, .bit12_set + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + LD A, 0x1 + CP C + RET + +.bit2_set: + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + LD A, 0x2 + CP C + RET + +.bit12_set: + LD A, 0x0 + OUT (SYS_DD17PB), A + LD A, 3 + CP C + RET + +paint_task: + POP HL ; L=x0, H=Y + LD (M_VARS.paint_var3), HL + EX DE, HL + + POP HL ; L=x1, H=mode + LD A, H + OR A + JP Z, paint_exit ; jump for mode=0 + + ; calc leftmost pixel address, mask for draw horisontal line + LD (M_VARS.paint_var1), HL + CALL calc_px_addr + LD (M_VARS.esc_param+1), HL + LD C, B + LD A, 0x80 +.lmp_mask: + RLCA + DEC B + JP P, .lmp_mask + LD (M_VARS.esc_param+3), A + ; calc rightmos pixel address and mask + LD A, (M_VARS.paint_var1) + LD E, A + LD A, (M_VARS.paint_var4) + LD D, A + CALL calc_px_addr + LD (M_VARS.esc_param+4), HL + LD D, B + LD A, 0x80 +.rmp_mask: + RLCA + DEC B + JP P, .rmp_mask + LD (M_VARS.esc_param+6), A + LD A, (M_VARS.esc_param+3) ; TODO: unused code + + XOR A +.lmi_mask: + SCF + RLA + DEC C + JP P, .lmi_mask + RRA + LD E, A ; E - left inv mask + + XOR A +.rmi_mask: + SCF + RLA + DEC D + JP P, .rmi_mask + CPL + LD D, A ; D - right inv mask + + LD (M_VARS.pixel_mask_r), A + LD HL, (M_VARS.esc_param+1) ; HL -> lext pix address + LD A, (M_VARS.esc_param+5) ; right pix address (low byte) + SUB H ; delta x + RRCA ; 2 byte for 8 pix + LD C, A ; C - line width + CALL draw_line_h + JP ep_task_end + +paint_exit: + LD HL, (M_VARS.tmp_color) ; restore previous current color + LD (M_VARS.curr_color), HL + LD HL, (M_VARS.paint_sp_save) ; restore previous stack + LD SP, HL + RET + +;--------------------------------------------------- +; Draw horizontal line +; Inp: C - width +; DE - left & right pixel mask +; HL - address of first byte of line +;--------------------------------------------------- +draw_line_h: + ; Access to VideoRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, C + OR A + JP NZ, .width_ne0 + LD A, E ; join left and right masks + OR D +.next_byte: + LD E, A +.width_ne0: + LD B, E + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Get pixels, apply colors + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A ; store first + ; Same for second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; move to next byte + INC H + LD A, C + OR A + JP Z, .complete + DEC C +.r_mask: + ; use right mask for last right byte + LD A, (M_VARS.pixel_mask_r) + JP Z, .next_byte +.full_8: + LD (HL), E + INC H + LD (HL), D + INC H + DEC C + JP NZ, .full_8 + JP .r_mask +.complete: ; TODO: duplicate close_vram_ret + ; Disable VideoRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +;--------------------------------------------------- +; 2x1y1x2y2 Draw Line +;--------------------------------------------------- +esc_draw_line: + LD HL, M_VARS.esc_param + LD E, (HL) ; E=X1 + INC HL + LD D, (HL) ; D=Y1 + INC HL + LD A, (HL) + INC HL + LD H, (HL) ; H=Y2 + LD L, A ; L=X2 + CP E + JP C, .x1_le_x2 + EX DE, HL ; exchange if X1>X2 +.x1_le_x2: + LD (M_VARS.esc_param), HL ; store x1,y1 back + LD A, E + SUB L + LD L, A ; L - width + LD A, D + SUB H + LD H, A ; H - height + PUSH AF + JP NC, .pos_height + ; change sign + CPL + INC A + LD H, A +.pos_height: + EX DE, HL + LD HL, (M_VARS.esc_param) + EX DE, HL + JP Z, height0 + LD A, L + OR A + JP Z, .width0 + LD B, A + POP AF + LD A, 0x0 + ADC A, A + LD (M_VARS.esc_param+4), A + ; HL = E/B height/width + LD E, H + LD C, 16 + LD D, 0 +.next_16: + ADD HL, HL + EX DE, HL + ADD HL, HL + EX DE, HL + LD A, D + JP C, .edl_l4 + CP B + JP C, .edl_l5 +.edl_l4: + SUB B + LD D, A + INC HL +.edl_l5: + DEC C + JP NZ, .next_16 + LD DE, 0x0 + PUSH DE + ; save result at stack + PUSH HL + + LD HL, (M_VARS.esc_param) ; x1,y1 + EX DE, HL + LD C, B + CALL calc_px_addr + ; HL - address, B - offset in byte + ; make mask + LD A, 10000000b +.roll_l: + RLCA + DEC B + JP P, .roll_l + CPL + LD B, A ; b - inv mask + +.edl_l7 + POP DE + EX (SP), HL ; save HL on top of stack + LD A, H + ADD HL, DE + SUB H + CPL + INC A + EX (SP), HL + PUSH DE + PUSH BC + LD C, A + EX DE, HL + + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Access VideoRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + LD A, (M_VARS.esc_param+4) ; sign of delta Y + OR A + JP NZ, .next_down +.next_up: + ; firs byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + DEC H + LD A, C + OR A + JP Z, .is_last + DEC C + ; draw up + DEC L + JP .next_up +.next_down: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; + DEC H + LD A, C + OR A + JP Z, .is_last + DEC C + ; draw down + INC L + JP .next_down +.is_last: + ; Disable VideoRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + POP BC + LD A, B + ; <<1px + SCF + RLA + JP C, .edl_l11 + RLA + INC H + INC H +.edl_l11 + LD B, A + DEC C + JP NZ, .edl_l7 + POP HL + POP HL + RET + +; -------------------------------------------------- +; draw vertical line +; Inp: DE - YX +; L - length +; -------------------------------------------------- +.width0 + LD C, H + CALL calc_px_addr + + ; make pixel mask + LD A, 10000000b +.edl_l13: + RLCA + DEC B + JP P, .edl_l13 + CPL + LD B, A + + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + POP AF + + ; Enable VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + JP C, .next_row_down + +.next_row_up: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next Y + DEC H + LD A, C + OR A + JP Z, close_vram_ret + DEC C + ; dec row + DEC L + JP .next_row_up + +.next_row_down: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next address + DEC H + LD A, C + OR A + JP Z, close_vram_ret + DEC C + ; inc row + INC L + JP .next_row_down + +close_vram_ret + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; draw horizontal line +; Inp: DE - YX +; L - length +; -------------------------------------------------- +height0 + POP AF + LD C, L + LD A, L + OR A + JP NZ, .len_ne0 + INC C ; length 1 at least +.len_ne0: + CALL calc_px_addr + ; make pixel mask + LD A, 10000000b +.edl_l19 + RLCA + DEC B + JP P, .edl_l19 + CPL + LD B, A + + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + + ; Enable VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + +.next_col: + ; set 1st byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; set 2nd byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next byte + DEC H + ; next (right) horizontal pixel + LD A, B + SCF + RLA + JP C, .edl_l21 + RLA + INC H + INC H +.edl_l21 + LD B, A + DEC C + JP NZ, .next_col + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; ESC Draw Dot +; -------------------------------------------------- +esc_draw_dot: + LD HL, (M_VARS.esc_param) + EX DE, HL + CALL calc_px_addr + LD A, 0x80 +edd_l1 + RLCA + DEC B + JP P, edd_l1 + LD B, A + LD A, (M_VARS.esc_param+2) + CP 0x3 + JP Z, edd_ep_task_end + LD A, B + CPL + LD B, A + LD A, (M_VARS.esc_param+2) + CP 0x2 + JP Z, edd_ep_fm_0 + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, (HL) + AND B + LD (HL), A + INC H + LD A, (HL) + AND B + LD (HL), A + LD A, 0x0 + OUT (SYS_DD17PB), A + RET +edd_ep_fm_0 + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + LD A, 0x0 + OUT (SYS_DD17PB), A + RET +edd_ep_task_end + CALL get_pixel + LD (M_VARS.esc_var3), A + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_picture: + LD HL, (M_VARS.esc_param+3) + LD A, (HL) + CP ':' + RET NZ + INC HL + LD E, (HL) + INC HL + LD D, (HL) + INC HL + LD A, (HL) + LD (M_VARS.esc_var0), A + INC HL + LD A, (HL) + LD (M_VARS.esc_var1), A + INC HL + PUSH HL + LD C, (HL) + INC HL + LD B, (HL) + INC HL + INC HL + EX DE, HL + PUSH DE + + ; Enable VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + CALL pict_sub1 + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + + POP DE + POP HL + LD (HL), C + INC HL + LD (HL), B + CALL pict_sub2 ; TODO: replace call+ret to jp; + RET + +pict_sub1: + LD A, (M_VARS.esc_param) + CP ASCII_EM + JP Z, gih_up + CP ASCII_CAN + JP Z, gih_rt + CP ASCII_SUB + JP Z, gih_ctrl_z + CP ASCII_BS + JP Z, gih_bs + CP ASCII_US + JP Z, pict_clr + RET + +pict_clr: + LD L, C + LD H, B + LD A, (M_VARS.esc_var0) + LD C, A + LD A, (M_VARS.esc_var1) + LD B, A + CALL put_image + POP HL + POP HL + POP HL + RET + +ehd_l1: + CP 0x2 + JP Z, get_image_hdr + CP 0x3 + JP Z, m_fn_39 + RET + +; -------------------------------------------------- +; Function 39 +; -------------------------------------------------- +m_fn_39: + LD HL, (M_VARS.esc_param+2) ; pr 3,4 + INC L + LD C, L + LD B, H + LD E, L + CALL dc_mul_e_h + ADD HL, HL + EX DE, HL + LD HL, (M_VARS.esc_param) ; par 1,2 + PUSH BC + PUSH DE + LD BC, 10 + LD E, L + LD D, H + ADD HL, BC + EX DE, HL + LD (HL), E + INC HL + LD (HL), D + INC HL + POP BC + LD A, 4 +.l1: + PUSH AF ; TODO: remove AF not changed + EX DE, HL + ADD HL, BC + EX DE, HL + LD (HL), E + INC HL + LD (HL), D + INC HL + POP AF ; TODO: remove AF not changed + DEC A + JP NZ, .l1 + EX DE, HL + LD HL, 0x0 + ADD HL, BC ; HL=BC + ADD HL, BC ; HL=2*BC + ADD HL, HL ; HL=4*BC + ADD HL, BC ; HL=5*BC + ADD HL, HL ; HL=10*BC + EX DE, HL ; DE=10*BC + LD A, 0x0 + LD B, A ; B=A=0 + ; fill DE bytes at [HL] with 0 +.l2: + LD (HL), B + INC HL + DEC DE + CP E + JP NZ, .l2 + CP D + JP NZ, .l2 + + XOR A + LD (M_VARS.esc_var0), A + POP BC + LD HL, (M_VARS.esc_param) + LD DE, 10 + ADD HL, DE +.l3: + EX DE, HL + LD HL, (M_VARS.esc_param+4) + EX DE, HL + PUSH BC + CALL fn39_sub2 + POP BC + LD A, (M_VARS.esc_var0) + ADD A, 0x2 + LD (M_VARS.esc_var0), A + CP 10 + RET Z + JP .l3 + +; --------------------------------------------------- +; Function 3C +; --------------------------------------------------- +get_image_hdr: + LD HL, (M_VARS.esc_param+4) + LD (HL), 58 ; ':' + INC HL + PUSH HL + LD HL, (M_VARS.esc_param+2) + INC L + LD C, L + LD A, H + ADD A, 0x4 + LD B, A + LD H, B + LD E, C + CALL dc_mul_e_h + ADD HL, HL + EX DE, HL + POP HL + LD (HL), E + INC HL + LD (HL), D + INC HL + LD (HL), C + INC HL + LD (HL), B + INC HL + EX DE, HL + LD HL, (M_VARS.esc_param) + ADD HL, HL + EX DE, HL + PUSH BC + PUSH HL + CALL calc_px_addr + POP DE + LD A, L + LD (DE), A + INC DE + LD A, H + LD (DE), A + INC DE + LD A, B + LD (DE), A + INC DE + POP BC + LD A, 0x1 + OUT (SYS_DD17PB), A + CALL get_image ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; = +; --------------------------------------------------- +esc_get_put_image: + LD A, (M_VARS.esc_param+6) + CP 0x2 + JP NC, ehd_l1 + LD HL, M_VARS.esc_param + LD E, (HL) + INC HL + LD D, (HL) + INC HL + LD C, (HL) + INC HL ; TODO: next call to calc_px_addr + LD B, (HL) ; destroy value of B and HL + CALL calc_px_addr + EX DE, HL + LD HL, (M_VARS.esc_param+4) + LD A, H + CP 128 + RET C + + CP 184 + RET NC + + EX DE, HL + + ; Enable VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, (M_VARS.esc_param+6) + OR A + JP NZ, put_image + +; --------------------------------------------------- +; Get image from VRAM to user buffer +; Inp: HL -> VRAM[x,y] +; DE -> buffer +; BC - width, height +; --------------------------------------------------- +get_image: + PUSH HL + PUSH BC +.next_row: + ; byte 1 + LD A, (HL) + LD (DE), A + INC H ; next Y (row) + INC DE + ; byte 2 ; next dst addr + LD A, (HL) + LD (DE), A + INC H + LD A, H + CP 128 ; last row? + JP NZ, .l2 + LD H, 0x40 ; reset Y +.l2: + INC DE + DEC C + JP NZ, .next_row + POP BC + POP HL + INC L + DEC B ; dec width + JP NZ, get_image + JP img_task_end + +; --------------------------------------------------- +; Put image from buffer to VRAM +; Inp: HL -> VRAM[x,y] +; DE -> buffer +; BC - width, height +; --------------------------------------------------- +put_image: + PUSH HL + PUSH BC +.next_row: + ; two bytes for 8 pixels + ; byte 1 + LD A, (DE) ; get from buffer + LD (HL), A ; put to screen + INC H ; next Y (row) + INC DE ; next src addr + ; byte 2 + LD A, (DE) + LD (HL), A + INC DE + INC H + LD A, H + CP 128 ; last row? + JP NZ, .l2 + LD H, 0x40 ; reset +.l2: + DEC C + JP NZ, .next_row + POP BC + POP HL + ; next column + INC L + DEC B + JP NZ, put_image + +img_task_end: + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +fn39_sub2: + DEC C +.l1: + PUSH BC +.l2: + EX DE, HL + PUSH BC + PUSH HL + LD L, (HL) + LD H, 0x0 + LD A, (M_VARS.esc_var0) + LD B, A + OR A + JP Z, .l4 +.l3: + ADD HL, HL + DEC A + JP NZ, .l3 +.l4: + LD A, B + LD C, L + LD B, H + POP HL + INC HL + PUSH HL + LD L, (HL) + LD H, 0x0 + OR A + JP Z, .l6 +.l5: + ADD HL, HL + DEC A + JP NZ, .l5 +.l6: + EX DE, HL + LD A, (HL) + OR C + LD (HL), A + INC HL + LD A, (HL) + OR E + LD (HL), A + INC HL + LD (HL), B + INC HL + LD (HL), D + DEC HL + POP DE + INC DE + POP BC + DEC C + JP NZ, .l2 + POP BC + INC HL + INC HL + DEC B + JP NZ, .l1 + RET + +; -------------------------------------------------- +; Handle ASCII_CAN symbol (cursor right) +; -------------------------------------------------- +gih_rt: + DEC DE + LD A, (DE) + ADD A, 0x2 + LD (DE), A + CP 9 + RET C + LD A, 0x2 + LD (DE), A + INC DE + PUSH BC + LD H, D + LD L, E + INC HL + INC HL + LD A, (M_VARS.esc_var0) + PUSH AF + DEC A + LD (M_VARS.esc_var0), A + INC A + ADD A, A + ADD A, B + CP 128 + JP C, .l1 + SUB 0x40 +.l1: + LD B, A + LD A, (M_VARS.esc_var1) +.l2: + PUSH AF + LD A, (M_VARS.esc_var0) +.l3: + PUSH AF + LD A, (HL) + LD (DE), A + INC HL + INC DE + LD A, (HL) + LD (DE), A + INC HL + INC DE + POP AF + DEC A + JP NZ, .l3 + LD A, (BC) + LD (DE), A + INC DE + INC HL + INC B + LD A, (BC) + LD (DE), A + INC HL + INC DE + DEC B + INC C + POP AF + DEC A + JP NZ, .l2 + POP AF + LD (M_VARS.esc_var0), A + POP BC + INC B + INC B + LD A, B + CP 0x80 + RET NZ + LD B, 0x40 + RET + +; -------------------------------------------------- +; Handle ASCII_BS (BackSpace) symbol +; -------------------------------------------------- +gih_bs: + DEC DE + LD A, (DE) + SUB 0x2 + LD (DE), A + RET NC + + LD A, 6 + LD (DE), A + INC DE + PUSH BC + ADD HL, DE + DEC HL + LD D, H + LD E, L + DEC HL + DEC HL + LD A, (M_VARS.esc_var1) + ADD A, C + DEC A + LD C, A + LD A, B + DEC A + CP 0x3f + JP NZ, .l1 + LD A, 0x7f ; [DEL]? +.l1: + LD B, A + LD A, (M_VARS.esc_var0) + PUSH AF + DEC A + LD (M_VARS.esc_var0), A + LD A, (M_VARS.esc_var1) +.l2: + PUSH AF + LD A, (M_VARS.esc_var0) +.l3: + PUSH AF + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + POP AF + DEC A + JP NZ, .l3 + LD A, (BC) + LD (DE), A + DEC HL + DEC DE + DEC B + LD A, (BC) + LD (DE), A + DEC HL + DEC DE + INC B + DEC C + POP AF + DEC A + JP NZ, .l2 + POP AF + LD (M_VARS.esc_var0), A + POP BC + DEC B + DEC B + LD A, B + CP 0x3e + RET NZ + LD B, 0x7e + RET + +; -------------------------------------------------- +; Handle ASCII_SUB symbol +; -------------------------------------------------- +gih_ctrl_z: + PUSH BC + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, A + ADD A, E + LD L, A + LD H, D + LD A, (M_VARS.esc_var1) + ADD A, C + LD C, A + PUSH BC + LD A, (M_VARS.esc_var1) + DEC A + DEC A + LD C, A +.l1: + LD A, (M_VARS.esc_var0) + LD B, A +.l2: + LD A, (HL) + LD (DE), A + INC HL + INC DE + LD A, (HL) + LD (DE), A + INC HL + INC DE + DEC B + JP NZ, .l2 + DEC C + JP NZ, .l1 + POP BC + LD L, 0x2 +.l3: + LD A, (M_VARS.esc_var0) + LD H, A + PUSH BC +.l4: + LD A, (BC) + LD (DE), A + INC DE + INC B + LD A, (BC) + LD (DE), A + INC DE + INC B + LD A, B + CP 0x80 + JP NZ, .l5 + LD B, 0x40 +.l5: + DEC H + JP NZ, .l4 + POP BC + INC C + DEC L + JP NZ, .l3 + POP BC + INC C + INC C + RET + +; -------------------------------------------------- +; Handle ASCII_EM symbol +; -------------------------------------------------- +gih_up: + PUSH BC + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, B + CP 128 + JP Z, .l1 + JP C, .l1 + SUB 64 +.l1: + DEC A + LD B, A + DEC C + PUSH BC + ADD HL, DE + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, A + LD E, A + LD A, L + SUB E + LD E, A + LD D, H + DEC DE + DEC HL + EX DE, HL + LD A, (M_VARS.esc_var1) + DEC A + DEC A + LD C, A +.l2: + LD A, (M_VARS.esc_var0) + LD B, A +.l3: + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + DEC B + JP NZ, .l3 + DEC C + JP NZ, .l2 + POP BC + LD L, 0x2 + +.l4: + LD A, (M_VARS.esc_var0) + LD H, A + PUSH BC + +.l5: + LD A, (BC) + LD (DE), A + DEC DE + DEC B + LD A, (BC) + LD (DE), A + DEC DE + DEC B + LD A, B + CP 0x3f + JP NZ, .l6 + LD B, 0x7f + +.l6: + DEC H + JP NZ, .l5 + POP BC + DEC C + DEC L + JP NZ, .l4 + POP BC + DEC C + DEC C + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +pict_sub2: + PUSH DE + DEC DE + LD A, (DE) + LD E, A + LD D, 0x0 + LD HL, (M_VARS.esc_param+1) + ADD HL, DE + LD E, (HL) + INC HL + LD D, (HL) + POP HL + PUSH BC + PUSH HL + PUSH HL + LD HL, (M_VARS.esc_param+3) + INC HL + LD C, (HL) + INC HL + LD B, (HL) + POP HL + ADD HL, BC + LD C, L + LD B, H + POP HL + CALL mov_hl_bc + LD A, (M_VARS.esc_param+5) + OR A + JP Z, .l1 + EX DE, HL +.l1: + LD A, (M_VARS.esc_var1) + SUB 0x4 +.l2: + PUSH AF + LD A, (M_VARS.esc_var0) +.l3: + PUSH AF + LD A, (DE) + INC DE + PUSH DE + PUSH AF + LD A, (DE) + LD E, A + POP AF + LD D, A + OR E + CPL + PUSH AF + AND (HL) + OR D + LD (BC), A + INC BC + INC HL + POP AF + AND (HL) + OR E + LD (BC), A + INC BC + INC HL + POP DE + INC DE + POP AF + DEC A + JP NZ, .l3 + POP AF + DEC A + JP NZ, .l2 + LD A, (M_VARS.esc_param+5) + OR A + JP Z, .l4 + EX DE, HL +.l4: + CALL mov_hl_bc + POP DE + EX DE, HL + LD A, (M_VARS.esc_var0) + LD C, A + LD A, (M_VARS.esc_var1) + LD B, A + LD A, 0x1 + OUT (SYS_DD17PB), A + CALL put_image ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Move form [HL] to [BC] count of bytes +; Inp: HL -> src +; BC -> dst +; esc_var0*4 - count +; --------------------------------------------------- +mov_hl_bc: + PUSH DE + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, A + LD E, A ; E = param * 4 + ; move [HL] -> [BC] E bytes +.next: + LD A, (HL) + LD (BC), A + INC HL + INC BC + DEC E + JP NZ, .next + POP DE + RET + +; --------------------------------------------------- +; Draw circle +; Inp: param x,y,radius, aspect_x, aspect_y +; --------------------------------------------------- +esc_draw_circle: + LD A, (M_VARS.esc_param+2) ; radius + LD B, A + OR A + RET Z ; exit ir radius 0 + LD A, 0x7f + CP B + RET M ; exit if radius>127 + + XOR A + LD D, A ; 0 + LD E, B ; r + CALL dc_draw_8px + + LD A, 1 + LD H, A + SUB B + LD C, A + LD A, B + RLCA + LD B, A + LD A, 0x1 + SUB B + LD L, A + CCF ; TODO: unused +.l1: + INC D + LD A, E + CP D + JP Z, dc_draw_8px + CALL dc_draw_8px + LD A, H + ADD A, 0x2 + LD H, A + LD A, L + ADD A, 0x2 + LD L, A + LD A, C + ADD A, H + LD C, A + JP NC, .l1 +.l2: + CCF ; TODO: unused + INC D + DEC E + LD A, D + CP E + JP Z, dc_draw_8px + SUB E + CP 0x1 + RET Z + LD A, E + SUB D + CP 0x1 + JP Z, dc_draw_8px + CALL dc_draw_8px + LD A, H + ADD A, 0x2 + LD H, A + LD A, L + ADD A, 0x4 + LD L, A + JP NC, .l3 + CCF ; TODO: unused +.l3: + LD A, C + ADD A, L + LD C, A + JP NC, .l1 + JP .l2 + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_8px: + PUSH HL + PUSH DE + PUSH BC + PUSH DE + CALL dc_aspect_ratio_1 + LD HL, (M_VARS.esc_param) ; HL=Y,X + CALL dc_draw_4px_bc + POP DE + CALL dc_aspect_ratio2 + LD HL, (M_VARS.esc_param) ; HL=Y,X + CALL dc_draw_4px_cb + POP BC + POP DE + POP HL + XOR A + RET + +; --------------------------------------------------- +; Scale circle axis dy specified aspect ratio +; if aspect_x = 0 C = D else C = D * aspect_x / 256 +; if aspect_y = 0 B = E else B = E * aspect_y / 256 +; --------------------------------------------------- +dc_aspect_ratio_1: + LD HL, (M_VARS.esc_param+3) ; aspect_x -> L, aspect_y -> H + LD A, L + OR A + LD C, D + LD B, E + JP NZ, .dc_ax_ne0 + LD A, H + OR A + JP NZ, .dc_ay_ne0 + RET +.dc_ax_ne0: + LD A, H + LD H, L + LD E, C + CALL dc_mul_e_h + LD C, E + OR A + RET Z +.dc_ay_ne0: + LD H, A + LD E, B + CALL dc_mul_e_h + LD B, E + RET + +; --------------------------------------------------- +; if aspect_x = 0 B = E else B = E * aspect_x / 256 +; if aspect_y = 0 C = D else C = D * aspect_y / 256 +; --------------------------------------------------- +dc_aspect_ratio2: + LD HL, (M_VARS.esc_param+3) ; aspect_x -> L, aspect_y -> H + LD A, L + OR A + LD C, D + LD B, E + JP NZ, .dc_ax_ne0 + LD A, H + OR A + JP NZ, .dc_ay_ne0 + RET +.dc_ax_ne0: + LD A, H + LD H, L + LD E, B + CALL dc_mul_e_h + LD B, E + OR A + RET Z + +.dc_ay_ne0: + LD H, A + LD E, C + CALL dc_mul_e_h + LD C, E + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_mul_e_h: + LD D, 0x0 + LD L, D + ADD HL, HL + JP NC, .l1 + ADD HL, DE +.l1: + ADD HL, HL + JP NC, .l2 + ADD HL, DE +.l2: + ADD HL, HL + JP NC, .l3 + ADD HL, DE +.l3: + ADD HL, HL + JP NC, .l4 + ADD HL, DE +.l4: + ADD HL, HL + JP NC, .l5 + ADD HL, DE +.l5: + ADD HL, HL + JP NC, .l6 + ADD HL, DE +.l6: + ADD HL, HL + JP NC, .l7 + ADD HL, DE +.l7: + ADD HL, HL + JP NC, .l8 + ADD HL, DE +.l8: + LD E, H + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_4px_bc: + ; draw pixel(H+B, L+C) if in screen + LD A, H + ADD A, B + JP C, .l1 + LD D, A + LD A, L + ADD A, C + LD E, A + CALL dc_put_pixel +.l1: + ; draw pixel(H+B, L-C) if in screen + LD A, H + ADD A, B + JP C, .l2 + LD D, A + LD A, L + SUB C + LD E, A + CALL dc_put_pixel +.l2: + ; draw pixel(H-B, L-C) if in screen + LD A, H + SUB B + JP C, .l3 + LD D, A + LD A, L + SUB C + LD E, A + CALL dc_put_pixel +.l3: + ; draw pixel(H-B, L+C) if in screen + LD A, H + SUB B + RET C + LD D, A + LD A, L + ADD A, C + LD E, A + CALL dc_put_pixel ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_4px_cb: + ; draw pixel(H+C, L+B) if in screen + LD A, H + ADD A, C + JP C, .l1 + LD D, A + LD A, L + ADD A, B + LD E, A + CALL dc_put_pixel +.l1: + ; draw pixel(H+C, L-B) if in screen + LD A, H + ADD A, C + JP C, .l2 + LD D, A + LD A, L + SUB B + LD E, A + CALL dc_put_pixel +.l2: + ; draw pixel(H-C, L-B) if in screen + LD A, H + SUB C + JP C, l3 + LD D, A + LD A, L + SUB B + LD E, A + CALL dc_put_pixel +l3: + ; draw pixel(H-C, L+B) if in screen + LD A, H + SUB C + RET C + LD D, A + LD A, L + ADD A, B + LD E, A + CALL dc_put_pixel ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Draw pixel on screen +; Inp: DE - X, Y +; --------------------------------------------------- +dc_put_pixel: + RET C ; return if CF set (out of screen) + PUSH HL + PUSH BC + CALL calc_px_addr + ; calculate B = pixel mask + LD A, 10000000b +.roll: + RLCA ; [07654321] <- [76547210], [7] -> CF + DEC B + JP P, .roll + CPL + LD B, A + ; DE = foreground color low and hi bytes + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Turn on Video RAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; Load VRAM[HL] byte (low byte), mask and set + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; Load VRAM[HL+1] byte (low byte), mask and set + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; Turn off Video RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + POP BC + POP HL + RET + + ; Full charset, Common + Latin letters (112*8=890) + INCLUDE "font-6x7.inc" + +; --------------------------------------------------- +; Convert 0h..Fh decimal value to symbol '0'..'F' +; --------------------------------------------------- +conv_nibble: + AND 0xf + ADD A, 0x90 + DAA + ADC A, 0x40 + DAA + LD C, A + RET + +; --------------------------------------------------- +; Print byte in HEX +; Inp: A - byte to print +; --------------------------------------------------- +m_hexb: + PUSH AF + RRCA + RRCA + RRCA + RRCA + CALL out_hex + POP AF + +out_hex: + CALL conv_nibble + CALL m_con_out ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Wtite RAM-Disk 64K to TAPE +; --------------------------------------------------- +m_tape_write_ram2: + LD HL, M_VARS.buffer + LD C, 128 +.cl_stack: + LD (HL), 0x0 + INC HL + DEC C + JP NZ, .cl_stack + LD HL, M_VARS.buffer + LD DE, 0xffff + ; write empty block + ; DE - block ID + ; HL -> block + CALL m_tape_write + CALL twr2_delay + LD DE, 0x0 + CALL m_tape_write + CALL twr2_delay + LD BC, 512 + LD DE, 0x0 +.nxt_blk: + PUSH BC + LD HL, M_VARS.buffer + CALL m_ramdisk_read + INC DE + CALL m_tape_write + CALL twr2_delay + POP BC + DEC BC + LD A, B + OR C + JP NZ, .nxt_blk + RET + +; --------------------------------------------------- +; Pause between blocks on tape +; --------------------------------------------------- +twr2_delay: + LD BC, 250 +.delay: + DEC BC + LD A, B + OR C + JP NZ, .delay + RET + +; --------------------------------------------------- +; Read RAM-Disk 64K from TAPE +; --------------------------------------------------- +m_tape_read_ram2: + LD A, 100 + CALL m_tape_wait + OR A + JP NZ, .end + LD E, 6 + +.srch_first: + DEC E + JP Z, .not_found + ; read block + LD HL, M_VARS.buffer + CALL m_tape_read + CP 4 + JP Z, .end + OR A + JP NZ, .srch_first + LD A, B + OR C + JP NZ, .srch_first + + LD BC, 512 + LD DE, 0x0 + +.rd_next: + PUSH BC + ; Read block from tape + CALL m_tape_read + OR A + JP NZ, .rd_error + DEC BC + LD A, B + CP D + JP NZ, .inv_id + LD A, C + CP E + JP NZ, .inv_id + ; Ok, write block to RAM disk + CALL m_ramdisk_write + INC DE + POP BC + DEC BC + LD A, B + OR C + JP NZ, .rd_next + RET +.not_found: + LD HL, msg_no_start_rec + CALL me_out_strz ; TODO: replace call+ret to jp + RET +.rd_error: + CP 2 + JP Z, .err_ubi + CP 4 + JP Z, .err_ibu + LD HL, msg_checksum + CALL me_out_strz + CALL out_hexw + POP BC + RET + + ; Illegal sequence of blocks +.inv_id: + LD HL, msg_sequence + CALL me_out_strz + INC BC + CALL out_hexw + POP BC + RET + +.err_ubi: + LD HL, msg_ibg + CALL me_out_strz + POP BC + RET + + ; Interrupted by user +.err_ibu: + POP BC +.end: + LD HL, msg_break + CALL me_out_strz ; TODO: replace call+ret to jp + RET + +; -------------------------------------------------- +; Output hex word +; Inp: BC - word to output +; -------------------------------------------------- +out_hexw: + PUSH BC + LD A, B + CALL m_hexb + POP BC + LD A, C + CALL m_hexb ; TODO: replace call+ret to jp + RET + +msg_no_start_rec: + DB "NO START RECORD", 0 +msg_checksum: + DB "CHECKSUM ", 0 +msg_sequence: + DB "SEQUENCE ", 0 +msg_ibg: + DB "IBG", 0 +msg_break: + DB "BREAK", 0 + +; --------------------------------------------------- +; Out ASCIIZ message +; Inp: HL -> zero ended string +; --------------------------------------------------- +me_out_strz: + LD A, (HL) + OR A + RET Z + PUSH BC + LD C, A + CALL m_con_out + INC HL + POP BC + JP me_out_strz + + + +; --------------------------------------------------- +; Read from RAM-disk to RAM +; Inp: DE - source sector +; HL -> destination buffer +; --------------------------------------------------- +m_ramdisk_read: + PUSH HL + PUSH DE + LD A, D + ; Build value to access ext RAM (A17, A16, 32k bits) + AND 00000111b ; A17, A16, Low 32K bits of memory mapper + ADD 0x2 ; Calc A16, A17 address lines + OR 0x0 ; TODO: nothing, remove + LD B, A ; B - value to turn on access to Ext RAM + ; Calculate DE = address from sector number + XOR A + LD A, E ; E - low address + RRA ; [CF] -> [7:0] -> [CF] + LD D, A ; D = E/2 + LD A, 0x0 + RRA ; [CF] -> E + LD E, A +.read: + ; Access to ExtRAM + LD A, B + OUT (SYS_DD17PB), A + ; Get Byte + LD A, (DE) + LD C, A + ; Access to RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + ; Set Byte + LD (HL), C + ; HL++, DE++ + INC HL + INC DE + LD A, E + ADD A, A + JP NZ, .read ; jump if has more bytes + + ; Access to RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + + POP DE + POP HL + RET + +; --------------------------------------------------- +; Write sector to RAM disk +; Inp: HL -> source buffer +; DE - destination sector +; --------------------------------------------------- +m_ramdisk_write: + PUSH HL + PUSH DE + LD A, D + AND 0x7 + ADD 0x2 ; build value to access ext RAM (A17, A16, 32k bits) + OR 0x0 ; TODO: remove unused + LD B, A + XOR A + LD A, E + RRA + LD D, A + LD A, 0x0 + RRA + LD E, A +.wr_byte: + LD A, 0x0 + OUT (SYS_DD17PB), A + LD C, (HL) + LD A, B + OUT (SYS_DD17PB), A + LD A, C + LD (DE), A + INC HL + INC DE + LD A, E + ADD A, A + JP NZ, .wr_byte + LD A, 0x0 + OUT (SYS_DD17PB), A + POP DE + POP HL + RET + +; -------------------------------------------------- +; Write block to Tape +; In: DE - block ID, +; HL -> block of data. +; -------------------------------------------------- +m_tape_write: + PUSH HL + PUSH DE + PUSH DE + LD BC, 2550 + LD A, PIC_POLL_MODE ; pool mode + OUT (PIC_DD75RS), A + LD A,TMR0_SQWAVE ; tmr0, load lsb+msb, sq wave, bin + OUT (TMR_DD70CTR), A + LD A, C + OUT (TMR_DD70C1), A + LD A, B + OUT (TMR_DD70C1), A + ; Write Hi+Lo, Hi+Lo + LD DE, 4 ; repeat next 4 times +.l1: + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; check rst4 from timer#0 + JP NZ, .l1 + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH ; tape level hi + JP NZ, .set_lvl + LD A, TL_LOW ; tape level low +.set_lvl: + OUT (DD67PC), A ; set tape level + LD A, TMR0_SQWAVE ; tmr0, load lsb+msb, swq, bin + ; timer on + OUT (TMR_DD70CTR), A + LD A, C + OUT (TMR_DD70C1), A + LD A, B + OUT (TMR_DD70C1), A + DEC E + JP NZ, .l1 + +.l2: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .l2 + + ; Write 00 at start + LD A, 0x0 + CALL m_tape_wr_byte + ; Write 0xF5 marker + LD A, 0xf5 + CALL m_tape_wr_byte + LD E, 0x0 ; checksum=0 + ; Write block ID + POP BC + LD A, C + CALL m_tape_wr_byte + LD A, B + CALL m_tape_wr_byte + ; Write 128 data bytes + LD B, 128 +.next_byte: + LD A, (HL) + CALL m_tape_wr_byte + INC HL + DEC B + JP NZ, .next_byte + ; Write checksum + LD A, E + CALL m_tape_wr_byte + ; Write final zero byte + LD A, 0x0 + CALL m_tape_wr_byte +.wait_end: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .wait_end + LD A, TL_MID ; tape level middle + OUT (DD67PC), A + POP DE + POP HL + RET + + +; ------------------------------------------------------ +; Write byte to tape +; Inp: A - byte top write +; D - current level +; E - current checksum +; ------------------------------------------------------ +m_tape_wr_byte: + PUSH BC + ; calc checksum + LD B, A + LD A, E + SUB B + LD E, A + LD C, 8 ; 8 bit in byte +.get_bit: + LD A, B + RRA + LD B, A + JP C, .bit_hi +.wait_t: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .wait_t + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; program for 360 cycles + LD A, 0x68 + OUT (TMR_DD70C1), A + LD A, 0x1 + OUT (TMR_DD70C1), A + ; change amplitude + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH + JP NZ, .out_bit + LD A, TL_LOW +.out_bit: + OUT (DD67PC), A + DEC C + JP NZ,.get_bit + POP BC + RET +.bit_hi: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .bit_hi + ; program for 660 cycles + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + LD A, 0x94 + OUT (TMR_DD70C1), A + LD A, 0x2 + OUT (TMR_DD70C1), A + ; change amplitude + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH + JP NZ, .out_bit_hi + LD A, TL_LOW +.out_bit_hi: + OUT (DD67PC), A + DEC C + JP NZ, .get_bit + POP BC + RET + +; ------------------------------------------------------ +; Load block from Tape +; In: HL -> buffer to receive bytes from Tape +; Out: A = 0 - ok, +; 1 - CRC error, +; 2 - unexpected block Id +; 4 - key pressed +; ------------------------------------------------------ +m_tape_read: + PUSH HL + PUSH DE + LD A, PIC_POLL_MODE ; pool mode + OUT (PIC_DD75RS), A + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A ; tmr0, load lsb+msb, sq wave + LD A, 0x0 + ; tmr0 load 0x0000 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + LD C, 3 +.wait_3_changes: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + LD A, B + ADD A, 4 + JP P, .wait_3_changes + DEC C + JP NZ, .wait_3_changes +.wait_4th_change: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + LD A, B + ADD A, 4 + JP M, .wait_4th_change + LD C, 0x0 +.wait_f5_marker: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + DEC A + RRA + LD A, C + RRA + LD C, A + CP 0xf5 + JP NZ, .wait_f5_marker + LD E, 0x0 ; checksum = 0 + ; Read blk ID + CALL m_tape_read_byte + JP NC, .err_read_id + LD C, D + CALL m_tape_read_byte + JP NC, .err_read_id + LD B, D + PUSH BC + ; Read block, 128 bytes + LD C, 128 +.read_next_b: + CALL m_tape_read_byte + JP NC, .err_read_blk + LD (HL), D + INC HL + DEC C + JP NZ, .read_next_b + + ; Read checksum + CALL m_tape_read_byte + JP NC, .err_read_blk + LD A, E + OR A + JP Z, .checksum_ok + LD A, 0x1 ; bad checksum +.checksum_ok: + POP BC +.return: + POP DE + POP HL + RET + +.err_read_blk: + POP BC + LD BC, 0x0 +.err_read_id: + LD A, 0x2 ; read error + JP .return +.key_pressed: + CALL m_con_in + LD C, A ; store key code in C + LD B, 0x0 + LD A, 0x4 + JP .return + +; ------------------------------------------------------ +; Read byte from Tape +; Out: D - byte +; CF is set if ok, cleared if error +; ------------------------------------------------------ +m_tape_read_byte: + PUSH BC + LD C, 8 +.next_bit: + CALL m_read_tape_bit + ; push bit from lo to hi in D + RRA + LD A, D + RRA + LD D, A + LD A, 4 + ADD A, B + JP NC, .ret_err + DEC C + JP NZ, .next_bit + ; calc checksum + LD A, D + ADD A, E + LD E, A + SCF +.ret_err: + POP BC + RET + +; ------------------------------------------------------ +; Read bit from tape +; Out: A - bit from tape +; B - time from last bit +; ------------------------------------------------------ +m_read_tape_bit: + IN A, (KBD_DD78PB) ; Read Tape bit 5 (data) + AND TAPE_P + LD B, A +.wait_change: + IN A, (KBD_DD78PB) + AND TAPE_P + CP B + JP Z, .wait_change + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; [360...480...660] 0x220=544d + IN A, (TMR_DD70C1) ; get tmer#0 lsb + ADD A, 0x20 + IN A, (TMR_DD70C1) ; get tmer#0 msb + LD B, A + ADC A, 0x2 + ; reset timer to 0 + LD A, 0x0 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + ; For 0 - 65535-360+544 -> overflow P/V=1 + ; For 1 - 65535-660+544 -> no overflow P/V=0 + RET P + INC A + RET + +; ------------------------------------------------------ +; Read bit from tape with keyboard interruption +; Out: A - bit from tape +; B - time from last bit +; ------------------------------------------------------ +read_tape_bit_kbd: + IN A, (KBD_DD78PB) + AND TAPE_P + LD B, A ; save tape bit state + ; wait change with keyboard check +.wait_change: + IN A, (PIC_DD75RS) + AND KBD_IRQ + JP NZ, .key_pressed + IN A, (KBD_DD78PB) + AND TAPE_P + CP B + JP Z, .wait_change + ; measure time + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; read lsb+msb + IN A, (TMR_DD70C1) + ADD A, 0x20 + IN A, (TMR_DD70C1) + LD B, A + ADC A, 0x2 + ; reset timer#0 + LD A, 0x0 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + ; flag P/V is set for 0 + RET P + INC A + RET +.key_pressed: + LD A, 0xff + RET + +; ------------------------------------------------------ +; Wait tape block +; Inp: A - periods to wait +; Out: A=4 - interrupded by keyboard, C=key +; ------------------------------------------------------ +m_tape_wait: + OR A + RET Z + PUSH DE + LD B, A +.wait_t4: + LD C,B + IN A, (KBD_DD78PB) + AND TAPE_P ; Get TAPE4 (Wait det) and save + LD E, A ; store T4 state to E +.wait_next_2ms: + LD A,TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; load 3072 = 2ms + XOR A + OUT (TMR_DD70C1), A + LD A, 0xc + OUT (TMR_DD70C1), A +.wait_tmr_key: + IN A, (PIC_DD75RS) + AND KBD_IRQ ; RST1 flag (keyboard) + JP NZ, .key_pressed + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; RST4 flag (timer out) + JP Z, .wait_no_rst4 + IN A, (KBD_DD78PB) + AND TAPE_P ; TAPE4 not changed? + CP E + JP NZ, .wait_t4 ; continue wait + JP .wait_tmr_key +.wait_no_rst4: + DEC C + JP NZ, .wait_next_2ms + XOR A + POP DE + RET + +.key_pressed: + CALL m_con_in + LD C, A ; C = key pressed + LD A, 0x4 ; a=4 interrupted by key + POP DE + RET + +; ------------------------------------------------------ +; Check block marker from Tape +; Out: A=0 - not detected, 0xff - detected +; ------------------------------------------------------ +m_tape_blk_detect: + IN A, (KBD_DD78PB) + AND TAPE_D ; TAPE5 - Pause detector + LD A, 0x0 + RET Z + CPL + RET + +; ====================================================== +; FDC DRIVER +; ====================================================== + + +fdc_unload_head: + LD A, 0x0 + OUT (FDC_DATA), A + LD A, FDC_RESTORE_UH_NV + OUT (FDC_CMD), A + NOP + NOP + +.wait_no_busy: + IN A, (FDC_CMD) + AND 00000101b ; Track0 , Busy + CP 00000100b + JP Z, .tr0_ok + + IN A, (FLOPPY) + RLCA ; MOTST -> CF + JP NC, .wait_no_busy + LD A, 0x20 + RET +.tr0_ok: + LD A, B + DEC A + LD A, 0x1 + JP Z, .b1 + LD (M_VARS.ul_A_var1), A + XOR A + LD (M_VARS.ul_A_var4), A + RET + +.b1: + LD (M_VARS.ul_B_var2), A + XOR A + LD (M_VARS.ul_B_var5), A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_select_drive: + PUSH AF + CALL delay_1.4mS + CP 0x1 ; TODO: DEC A to save 1b 3t + JP Z, .sel_A + LD A, 0x2 + JP .sel_B +.sel_A + LD A, 0x5 +.sel_B + LD B, A ; 010b or 101b + IN A, (FLOPPY) ; read Floppy controller reg + AND 0x40 ; SSEL + RRA ; SSEL for out + OR B ; 0x22 or 0x25 if WP + OUT (FLOPPY), A ; Select drive A or B + LD B, A + POP AF + DEC A + JP Z, .dpar_a + LD A, (bios_var2) + JP .dpar_b +.dpar_a + LD A, (BIOS.bios_var04) +.dpar_b + PUSH BC + LD B, A ; B = dpar_A or B + LD A, D ; compare with D? + CP B + JP C, .l_le ; D < B + SUB B + LD D, A + POP BC + LD A, C + OR 0x8 + LD C, A + LD A, B + AND 0x20 + OR A + RET NZ + LD A, B + OR 0x20 ; set SSEL to 1 + OUT (FLOPPY), A + CALL delay_136uS + RET +.l_le + POP BC + LD A, B + AND 0x20 + OR A + RET Z + LD A, B + AND 0x7 + OUT (FLOPPY), A + CALL delay_136uS + RET + +; --------------------------------------------------- +; Delay for 136uS +; --------------------------------------------------- +delay_136uS: + LD B, 16 ; 7 + +; --------------------------------------------------- +; Delay for B*8uS +; --------------------------------------------------- +delay_b: + DEC B ; 4 + JP NZ, delay_b ; 10 + RET ; 10 + +; --------------------------------------------------- +; Delay for 1.4mS +; --------------------------------------------------- +delay_1.4mS: + LD B, 175 ; 7 + JP delay_b ; 10 + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_read_floppy: + PUSH AF + CALL m_select_drive + POP AF + CALL m_start_seek_track + JP C, fdc_ret + CALL m_fdc_read_c_bytes + JP C, fdc_ret + XOR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_write_floppy: + PUSH AF + CALL m_select_drive + POP AF + CALL m_start_seek_track + JP C, fdc_ret + CALL m_fdc_write_bytes + JP C, fdc_ret + XOR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_start_seek_track: + CALL m_start_floppy + RET C + CALL m_fdc_seek_trk + RET C + RET ; TODO: remove + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_start_floppy: + LD B, A + LD A, (M_VARS.ul_var3) + CP B + JP Z, .need_m_start + CALL .wait_motor ; TODO: replace call+ret to jp + RET +.need_m_start: + IN A, (FLOPPY) + RLCA ; check MOTST + JP C, .wait_motor + IN A, (FDC_CMD) + AND FDC_NOT_READY ; not ready flag + RET Z + +; --------------------------------------------------- +; +; --------------------------------------------------- +.wait_motor: + PUSH BC + LD BC, 65535 + CALL fdc_init +.wait_rdy1: + IN A, (FDC_CMD) + AND FDC_NOT_READY + JP Z, .long_delay + IN A, (FLOPPY) + RLCA ; CF<-A[7] MOTST flag + JP NC, .wait_rdy1 + LD A, 0x20 + JP .mst_exi +.long_delay: + DEC BC + LD A, B + OR A + JP NZ, .long_delay +.mst_exi: + POP BC + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +fdc_init: + IN A, (FLOPPY) + AND 01001110b ; Get SSEL, DRSEL, MOT1, MOT0 + RRA + OUT (FLOPPY), A + OR 0x08 ; Set INIT bit + OUT (FLOPPY), A + RET + +; --------------------------------------------------- +; Seek track on floppy +; Inp: DE - track/sector +; --------------------------------------------------- +m_fdc_seek_trk: + LD A, B + DEC A + JP Z, .drv_b + LD A, (M_VARS.ul_A_var1) + OR A + CALL Z, fdc_unload_head + RET C + LD A, (M_VARS.ul_A_var4) + OUT (FDC_TRACK), A + LD A, D + LD (M_VARS.ul_A_var4), A + JP .cmn +.drv_b: + LD A, (M_VARS.ul_B_var2) + OR A + CALL Z, fdc_unload_head + RET C + LD A, (M_VARS.ul_B_var5) + OUT (FDC_TRACK), A + LD A, D + LD (M_VARS.ul_B_var5), A +.cmn: + LD A, (M_VARS.ul_var3) + CP B + LD A, B + LD (M_VARS.ul_var3), A + JP NZ, .l2 + IN A, (FDC_TRACK) + CP D + JP Z, .l2 + JP C, .l1 + LD A, (M_VARS.ul_var6) + OR A + JP NZ, .l2 + LD B, 0xff + CALL delay_b + LD A, 0x1 + LD (M_VARS.ul_var6), A + JP .l2 +.l1: + LD A, (M_VARS.ul_var6) + OR A + JP Z, .l2 + LD B, 0xff + CALL delay_b + LD A, 0x0 + LD (M_VARS.ul_var6), A +.l2: + LD A, D + OUT (FDC_DATA), A + LD A, 0x1f + OUT (FDC_CMD), A + NOP + NOP + IN A, (FDC_WAIT) + IN A, (FDC_CMD) + AND 0x19 + CP 0x0 + JP NZ, .l3 + JP .l4 +.l3: + SCF + LD A, 0x40 +.l4: + PUSH AF + LD A, E + OUT (FDC_SECT), A + POP AF + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_fdc_write_bytes: + LD A, C + OUT (FDC_CMD), A +.w_next: + IN A, (FDC_WAIT) + RRCA + LD A, (HL) + OUT (FDC_DATA), A + INC HL + JP C, .w_next + CALL fdc_check_status ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_fdc_read_c_bytes: + LD A, C + OUT (FDC_CMD), A + JP .l2 +.l1: + LD (HL), A + INC HL +.l2: + IN A, (FDC_WAIT) + RRCA + IN A, (FDC_DATA) + JP C, .l1 + CALL fdc_check_status ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Check fdc status for errors +; Out: CF set if errors +; --------------------------------------------------- +fdc_check_status: + IN A, (FDC_CMD) + AND 11011111b + CP 0x0 + JP Z, fdc_ret + SCF +fdc_ret: + RET + +filler1: + DB 20h + +; filler: +; ds 169, 0xff + +; ------------------------------------------------------ + +LAST EQU $ +CODE_SIZE EQU LAST-0xE000 +FILL_SIZE EQU ROM_CHIP_SIZE-CODE_SIZE + + + ASSERT m_start = 0xe051 + ASSERT m_out_strz = 0xe0f1 + ASSERT m_con_out_int = 0xe16d + ASSERT get_esc_param = 0xe187 + ASSERT esc_params_tab = 0xe1cb + ASSERT esc_handler_tab = 0xe1db + ASSERT esc_set_beep = 0xe1f9 + ASSERT m_print_hor_line = 0xe23a + ASSERT m_get_7vpix = 0xe2b4 + ASSERT esc_set_palette = 0xe2fe + ASSERT m_get_glyph = 0xe320 + ASSERT m_print_no_esc = 0xe349 + ASSERT calc_addr_40 = 0xe439 + ASSERT mp_mode_64 = 0xe4b8 + ASSERT calc_addr_80 = 0xe612 + ASSERT m_clear_screen = 0xe639 + ASSERT m_cursor_home = 0xe66c + ASSERT m_draw_cursor = 0xe69a + ASSERT m_handle_esc_code = 0xe77c + ASSERT handle_cc_common = 0xe7c4 + ASSERT handle_cc_80x25 = 0xe833 + ASSERT m_beep = 0xe85a + ASSERT esc_set_cursor = 0xe890 + ASSERT esc_set_vmode = 0xe8e9 + ASSERT esc_set_color = 0xe92f + ASSERT m_print_at_xy = 0xe943 + ASSERT game_sprite_tab = 0xea39 + ASSERT esc_draw_fill_rect = 0xeb64 + ASSERT draw_line_h = 0xeed1 + ASSERT esc_draw_line = 0xef0b + ASSERT esc_draw_dot = 0xf052 + ASSERT esc_picture = 0xf0a4 + ASSERT m_fn_39 = 0xf10f + ASSERT get_image_hdr = 0xf177 + ASSERT esc_get_put_image = 0xf1b5 + ASSERT pict_sub2 = 0xf3ca + ASSERT m_font_cp0 = 0xf5bc + ASSERT me_out_strz = 0xfb36 + ASSERT m_ramdisk_write = 0xfb6d + ASSERT m_tape_write = 0xfb97 + ASSERT m_tape_wr_byte = 0xfc0e + ASSERT m_tape_read_byte = 0xfcee + ASSERT m_read_tape_bit = 0xfd08 + ASSERT m_tape_wait = 0xfd58 + + + ; DISPLAY "Code size is: ", /A, CODE_SIZE + + +FILLER + DS FILL_SIZE, 0xFF + ; DISPLAY "Free size is: ", /A, FILL_SIZE + + ENDMODULE + + OUTEND + + OUTPUT m_vars.bin + ; put in separate waste file + INCLUDE "m_vars.inc" + OUTEND diff --git a/MON_r8_9c6c6546/ram.inc b/MON_r8_9c6c6546/ram.inc new file mode 100644 index 0000000..8c6c08e --- /dev/null +++ b/MON_r8_9c6c6546/ram.inc @@ -0,0 +1,49 @@ +; ======================================================= +; Ocean-240.2 +; +; RAM area at address: 0x0000 - 0x0100, used by CP/M and +; HW-Monitor +; By Romych 2026-02-03 +; ======================================================= + + IFNDEF _RAM + DEFINE _RAM + + MODULE RAM + +@warm_boot EQU 0x0000 ; Jump warm_boot (Restart) +@warm_boot_addr EQU 0x0001 ; address of warm boot entry point +@iobyte EQU 0x0003 ; Input/Output mapping +@cur_user_drv EQU 0x0004 ; [7:4] - curent user, [3:0] - current drive +@jp_bdos_enter EQU 0x0005 ; Jump bdos (CALL 5 to make CP/M requests) +@bdos_ent_addr EQU 0x0006 ; addres of BDOS entry point +@RST1 EQU 0x0008 +@RST1_handler_addr EQU 0x0009 +;RST2 EQU 0x0010 +;RST3 EQU 0x0018 +;RST4 EQU 0x0020 +;RST5 EQU 0x0028 +;RST6 EQU 0x0030 +;RST7 EQU 0x0038 +;reserve1 EQU 0x003b +@bios_var0 EQU 0x0040 ; 0xaa - bios init r8 +@bios_var1 EQU 0x0041 ; 0xaa - bios init r8 +@bios_var2 EQU 0x0042 ; 0x00 - bios init r8 +@bios_var3 EQU 0x0043 ; 0xff - bios init r8 +@interleave_0 EQU 0x0044 +;reserve2 EQU 0x0050 +@fcb1 EQU 0x005c ; Default FCB, 16 bytes +@fcb2 EQU 0x006c +;NMI_ISR EQU 0x0066 + +@dma_buffer EQU 0x0080 ; Default "DMA" 128 bytes buffer +@p_cmd_line_len EQU 0x0080 ; command line character count +@p_cmd_line EQU 0x0081 ; command line buffer +@fcb_ra_record_num EQU 0x00a1 +@bios_stack EQU 0x0100 +@tpa_start EQU 0x0100 ; start of program +@video_ram EQU 0x4000 + + ENDMODULE + + ENDIF \ No newline at end of file diff --git a/MON_r8_bedc54ad/.vscode/extensions.json b/MON_r8_bedc54ad/.vscode/extensions.json new file mode 100644 index 0000000..1fdc4e8 --- /dev/null +++ b/MON_r8_bedc54ad/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "maziac.asm-code-lens", + "maziac.dezog", + "maziac.hex-hover-converter", + "maziac.z80-instruction-set", + "maziac.sna-fileviewer" + ] +} diff --git a/MON_r8_bedc54ad/.vscode/tasks.json b/MON_r8_bedc54ad/.vscode/tasks.json new file mode 100644 index 0000000..9c09341 --- /dev/null +++ b/MON_r8_bedc54ad/.vscode/tasks.json @@ -0,0 +1,34 @@ +{ + "version": "2.0.0", + "tasks": [ + + { + "label": "make MONITOR (sjasmplus)", + "type": "shell", + "command": "sjasmplus", + "args": [ + "--sld=monitor.sld", + "--sym=monitor.labels", + "--raw=monitor.obj", + "--fullpath", + "monitor.asm" + ], + "problemMatcher": { + "owner": "sjasmplus", + "fileLocation": "autoDetect", + "pattern": { + "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "severity": 3, + "message": 4 + } + }, + "group": { + "kind": "build", + "isDefault": true + } + } + + ] +} \ No newline at end of file diff --git a/MON_r8_bedc54ad/BIN/MON_r8_bedc54ad.BIN b/MON_r8_bedc54ad/BIN/MON_r8_bedc54ad.BIN new file mode 100644 index 0000000000000000000000000000000000000000..474ecb13f14eac90134b966e488286f4bdd992e6 GIT binary patch literal 8192 zcmdTp3s)Q0nIjLLL^N0U{ofKqL_`+V8u< zkEY!pup`aA-~I0QzTbV!40q2}ZcCEO3vpXR+=C&mG{iNAxPu|CeU1C!D%Z5iJ+{i7 zOme%D+_81;`|I2enQM}{*i|kk#<^nL&!b$^EcZ}^E1cstEpm4*FVTHLE;vblFW5x) z21B$W=+jVEYEMsK@8h;VvR}PQQ$Zh{8D#6{nEv{!OnsQCpJM9jCmA}Uewv}1fJYUa zsGn!7l&WHeu{snLA29S^fXdTwO#OMh z^?#V#Y@P;JYXMdCb?aN9V?}@Z2yh-Lr?tkrOF39TJyBvE4;2+1w;hehs<w^rRp;l!mlnMphYIUYY^-yHf;=R$j*)ubJy>c)v$37M_`C77xNe zxF&pj!ukq!0P~%Iy9;jXZxIng629bqWpT+dih`oJq`BB0X8HoAjuC&ilTC zNyVNht-(5HjaFfuk)oCLD@??`!i2xJh4Ko&o~&+Ue=!;H{M2QiWPbMFu1bWa($HDN zy@)t~rVy&Fs;Y{FZ1x1xSf60n7bY~WqJflD$?-4dnxoUX&Q?44%Xx4D`6dlFBfOdnK`*?C&h=Flgx;aYo{~81Rllb41W#814l<7tJR<-%YtKz<8ZO7GGER1 zP1Tm_+3qPr7ElDVtr|yxqdyNiemn*EA55VOpx;|FXhZwJG&w^!5Wa2$jJ_cgWk&k* zNK zVcV7BQ!!1hG~EW9}#lXXJPl&lqAo{|fNg-O{WbV_oT@X(a3AF%DBYWNtS zZk6P0;j2<29k0|4uAB|7BEdQZi>`VKSfSWp1#)nI=L{&{IfI&R4TGl2Fld^dl8c18 zFz`f?2a4!HP z#J!+(k{vRa?VP#M5WX?PbPs1u}DH zr3_g8jk6?AVWAXnm5|A^qH;ltE1va8t1hT;!^p5WY3e6%U~xCr!O?}x1l);X2WXZR z!o)1>1JbN@l<~9%v}4k&%SM0rC#a8#_e4&PYCFRA4;e4}joD7vDh!!JrQDBaJHcSv z@ce8?e|vRxwei*uiVWHz`xT~9h|PvE5n&^MwdMD-uoLvpMsOQ=#Z_5}OaCjbD%=Z5 z6V`ud!o(oS8nWrx7ianU4;j863N8>D;-s6!WqbhQIDYIpVa_R^(VN?S^kx|A;M z?R`{RswD_*X~V-0Kip90DJ&dsn4WGJFPxsHJRWL#+H>kuDs}3VhbnA<&h+JJD5R*| z9lgCfaw$riEz8+j>e>AjM!by``=7--2d?PGg>Y))LNgIW9A4LG5QlviFYerl_v6|V zfbkS^4%uu+yPjj8j5IVu9`x_NMICoXEcNfh(f3^jh8i{og8X)* z{ykN{N8tMLBYg1&~BopaA3;EH7MW7te>_26^<1b8JGth_RCCry}+P#^`i_NT6iV`u2o!S=)O#Kyk*W= z|5wI-k!ik9EL_-jnE_U(xIPb(!(rg}3ja1|=b6U#N5gi3Y5z(X8rNa2eE~UqDKEszErgyM}k?zK4pp$leXcn&V%i>qH7+YZDWl69mZKJzJM*Fbn`s-#{4HOLTfs6Ny%dU0{iql#Dz|I`K}9t`R+{T@R|9_%5(=}5&G3U1PmM9uMci^=QxMY%~w^W zI|w5TI@s7U0^@ms9i8vMK!&;GJVyL}Xpo+k3qo?9aK|>dXV5vWcD`Fq4VI$jtOcT3 zSSNIss;c-d@1PkKRxS{QLg50Mc&W0I#{~17We+Y?daBN{Eep6N{DCKpR??sqf8Y^G zD>v$lKk%W7KQoa~k5>pRRQQ>6mK-E$;#t5ffx&@MX~B*$=5EsQ!-e{HFlS&^=;J?I zu(SeTj{jz%t_8ftksN1Wa=R~NVhF*`j?kJ>!8hdVBel`KXoMw#yKcXU19o*1rKtZQhGY#U`F zLP7MTS9ojD8KbH1)Q>S=Fyt0c)sgB**VsLa=f@5&o@s&g@xY>yqDI2Va1eYV{lsplX;1;g!$uTf3kR!l~rKnYm55r+&BLLwwC+JB1YHe-hIm$w|Gls zrBly-Z7~$$@4TjI2s9D#F_b^H`bjCqD98@~18gm~N@Vk~yH0x9vS{`-iMHs5L^Aj{ z;#q}89E_%o*cnB;cy#(2-@iniux`K>{vT0y9RZcX)6sMWkw+H7aXl0_#ej4`rq_SO z@Z0{%cx3y44W4~%9(bUDVui7V57}u&lUZU}R2=-*$zmy=(siVrHTmhuc4* z$f6!NtcyHpd&1_URf$L%j5V^KjzwT4)9I>p)v#hZAGeiUU=PM#hr1t4^Z~Omiz>(8)YgPoBx0 zXYvtOLopr}D_J?Lijj@wC~Pga0UfI9k^8R5=PyN&5Qx02A|Cd8@+wVmLmwNDZE=|N z>}1Rrf{h~-Gk-E)yXz#kV;0YzDkvfPO`sjDp?|hQI*?JaBr2&&1)-uruzy zYk$a=em=b&F$dxi&u?8e&p8)Z|3uA@$){(l;y#;A%~ry82QyDC_Y>wJX@9{z&;cKYssu3 zS*VEfBWd$JN?XQecHc6*O}PRIGD!EH|ERy^nE3KCt!O{f47&!cIMcBwzx#FJM3 z1eEP31Imuhr<;c#S>BVsx$6RSd{0&kc7GQ(?3-v*9m6j!@9BI7>A1dSc#k$B{&^W@ zhWO8kA#s{O4<_KnT0brkC%v~fv6q*7;NY{&_xvkPs5`ua?Z=>Qy59dG_EQPyCwS;5 zbbJBzmFnS~L{ar{J{Cn-lwo1RVk;Kgv8YcJeSz=k8*?ODPM&HNzncK~PJo{y@R_k= zH{dH96nxLAu?|4@5t375-2k5<@N;9QZ@@rKDEKRIwAa2_@qwAooYi&kq<!JkwrB@p0=nxZW5qws7E7$TZdK~-Qj8&p|Fqs3?hf%rEV;k<1$ zWa^AYqb}2;P~<2SmUN|nzRjQndVn4bC3eCShgPf87Z-g9`nF z3LQjbS#CBMj^m!Kgn?6Lr}e2aK&MKTK`G5yW-Vpj_)$9ZEoL1Iwbr03$W*EfIvotW zPN%cvW~cy%E%dJp#u^72tkw~euIa;kgD_(S+I2AK6jhp+mxrwq7(g@$hWfgHIPB0W zGnVD&QB12kPy-P~DHNo_bTFZ?Yz!6#5OOk8YtRA-HXvp? z9SkLSq|VOI)|tUQvu-0lEk?|F3wVeAWoN-<0pCb|qI=*Ukl=MaU(he3%1r#*$WQbR z{JWl?=}bnqU^enN(zHn=f`2@zU`^d_^}1hXm|rYLm7Wr0@d zwU#9pNXl|^b1i1_lX3!QKJ^#Jr<(Z$J~@kZ$(UH0gpVh@m0}EiyC^v6el`iPF_jX3 zxGFxGgxIG61*HVo4}D_Osws{0ZF2vXeIUszk`zKGl05y8cx>Ivt|ZGen*~2g65H3{ zb<9fA%RZX~nrD+6f&lMjFD5s+UuQ$f&I?e8kFA=B#9tlGZ{* zi0eroZ>>NuBMsLg?Bjjb9fZN}7PlmQolx+Hn#=Dyy!YP2<@X+FYQA?r)pYPc(;fF6 zxvQMI@4!7r4jgJaP)>brpOe~m?}5E{P#*7~zZt(G`M6!H;gK#$v7%g|oc-OF7MilO zx`V#rW?ZDdZZmbCW{<2Q4BvnLo)S9_0eL4Jae%V-2IYuiMMpkr!TYn$V4FMG1`{4W zE9J7UtajD4cxg2|uu5kHC-4PZnqV_@5sFJ7Ml`I^2`I`aaL};khFjC;ff7z+3#;7# z5E?>H!Ka7d1Q_UdcAtT_^KOfCZ0{QBDp^DM^p}Heu_EQH(6_4Pqpp_H}*;@Cl==g{W`il-WDhyZ*%?yJ_Vw|(S{9@ zK1slfiOYMkNgqfjp~ zd_t^|;TZM)I`|%1r`68!D#>AaHCW}0H3}>1_I(uh@w)wvQNOe6{Fqrj)8gw~(KfrK za_@k9r94}lt{4Osz9XYcCuO>v`@X!%?Pb3s!*End zhb+OW6>YEz92Nd3+ZP${#s6HtVvjRHYZo}oiLyPqfmthV7NsU`y7c{A{ zglu1i#~@8glM=Vc@ZM;d;WR14L2nvI0j>+eY$0K;1pA6)irt*z%2T^(N1{7e5#u|9 u<>Qq(o}kS(R-F>>NFjpTlXBSrJ8m0mBsk!FU#5g3soi`zzFqu(as4kwK`Q?M literal 0 HcmV?d00001 diff --git a/MON_r8_bedc54ad/README.md b/MON_r8_bedc54ad/README.md new file mode 100644 index 0000000..bd8054f --- /dev/null +++ b/MON_r8_bedc54ad/README.md @@ -0,0 +1,16 @@ +# Ocean-240.2 ROM Monitor V8 checksum bedc54ad + +Source codes of Monitor v8 for Ocean-240.2 with Floppy controller. +In Z80 mnemonics, but limited for i8080 instruction set. + +## Differences: + +1) Font. Russian letters б and д; + +## Compile: + +Code is located in memory at address: 0xE000..0xFFFF + + sjasmplus --sld=monitor.sld --sym=monitor.labels --raw=monitor.obj --fullpath monitor.asm + +To compile sources, use [sjasmplus Z80 assembler](https://github.com/z00m128/sjasmplus). diff --git a/MON_r8_bedc54ad/bios_entries.inc b/MON_r8_bedc54ad/bios_entries.inc new file mode 100644 index 0000000..117a2c8 --- /dev/null +++ b/MON_r8_bedc54ad/bios_entries.inc @@ -0,0 +1,41 @@ + +; ======================================================= +; Ocean-240.2 +; Definition of CPM BIOS entries to compile depended +; modules +; +; By Romych 2025-09-09 +; ====================================================== + IFNDEF _BIOS + DEFINE _BIOS + + MODULE BIOS + +boot_f EQU 0xD600 +wboot_f EQU 0xD603 +const_f EQU 0xD606 +conin_f EQU 0xD609 +conout_f EQU 0xD60C +list_f EQU 0xD60F +punch_f EQU 0xD612 +reader_f EQU 0xD615 +home_f EQU 0xD618 +seldsk_f EQU 0xD61B +settrk_f EQU 0xD61E +setsec_f EQU 0xD621 +setdma_f EQU 0xD624 +read_f EQU 0xD627 +write_f EQU 0xD62A +sectran_f EQU 0xD630 +reserved_f1 EQU 0xD633 +reserved_f2 EQU 0xD636 +tape_read_f EQU 0xD639 +tape_write_f EQU 0xD63C +tape_wait_f EQU 0xD63F + +bios_var04 EQU 0xD64B + + ENDMODULE + + + ENDIF diff --git a/MON_r8_bedc54ad/equates.inc b/MON_r8_bedc54ad/equates.inc new file mode 100644 index 0000000..b1b5622 --- /dev/null +++ b/MON_r8_bedc54ad/equates.inc @@ -0,0 +1,149 @@ +; ====================================================== +; Ocean-240.2 +; Equates for all assembly sources +; +; By Romych 2025-09-09 +; ====================================================== + + IFNDEF _EQUATES + DEFINE _EQUATES + +ADDLIST EQU 0x08 +ASCII_BELL EQU 0x07 ; Make Beep +ASCII_BS EQU 0x08 ; Move cursor left (Back Space) +ASCII_TAB EQU 0x09 ; Move cursor right +8 pos +ASCII_LF EQU 0x0A ; Move cursor down (Line Feed) +ASCII_FF EQU 0x0C ; Move cursor to home (Form Feed) +ASCII_CR EQU 0x0D ; Move gursor to 1st pos (Cariage Return) +ASCII_CAN EQU 0x18 ; Move cursor right +ASCII_EM EQU 0x19 ; Move cursor up +ASCII_SUB EQU 0x1A ; CTRL-Z - end of text file marker +ASCII_ESC EQU 0x1B ; +ASCII_US EQU 0x1F ; Clear screen +ASCII_SP EQU 0x20 +ASCII_DEL EQU 0x7F + +; ------------------------------------------------------ +BDOS_NFUNCS EQU 41 +BELL_PIN EQU 0x08 ; DD67 Pin PC3 - "BELL" +; ------------------------------------------------------ +CCP_COMMAND_SIZE EQU 5 ; max length of CCP command +CCP_COMMAND_COUNT EQU 3 ; Count of CCP commands +CCP_COMMAND_CNT EQU 6 +CCP_COMMAND_LEN EQU 4 + +CCP_SRC_ADDR EQU 0xc000 ; Address of CCP resident part in ROM +CCP_DST_ADDR EQU 0xb200 ; Address of CCP resident part in RAM +CCP_SIZE EQU 0x809 + +CPM_VERSION EQU 0x22 ; Version of CP/M as byte nibbles '2.2' + +CTRL EQU 0x5E ; ^ +CTRL_C EQU 0x03 ; Warm boot +CTRL_H EQU 0x08 ; Backspace +CTRL_E EQU 0x05 ; Move to beginning of new line (Physical EOL) +CTRL_J EQU 0x0A ; LF - Line Feed +CTRL_M EQU 0x0D ; CR - Carriage Return +CTRL_P EQU 0x10 ; turn on/off printer +CTRL_R EQU 0x12 ; Repeat current cmd line +CTRL_S EQU 0x13 ; Temporary stop display data to console (aka DC3) +CTRL_U EQU 0x15 ; Cancel (erase) current cmd line +CTRL_X EQU 0x18 ; Cancel (erase) current cmd line + +; ------------------------------------------------------ +DBPLIST EQU 0x0F +DEF_DISK_A_SIZE EQU 0x3F +DEF_DISK_B_SIZE EQU 0x0168 +DIR_BUFF_SIZE EQU 128 +DSK_MAP EQU 0x10 +DSK_MSK EQU 0x03 +DSK_SHF EQU 0x02 +DMA_BUFF_SIZE EQU 0x80 +; ------------------------------------------------------ +ENDDIR EQU 0xFFFF +ESC_CMD_END EQU 0x1A +;EXT_NUM EQU 12 ; Extent byte offset +; ------------------------------------------------------ +FALSE EQU 0x00 +FDC_DD80RB EQU 0x21 +FDC_NOT_READY EQU 0x80 +FDC_RESTORE_L EQU 0x08 +FDC_SEEK_LV EQU 0x1C +FDC_RESTORE_UH_NV EQU 0x03 ; Restore Unload Head, No Verify, 15ms Rate +FILE_DELETED EQU 0xE5 +FWF_MASK EQU 0x80 ; File Write Flag mask + +; --------------------------------------------------- +; FCB Offsets +; --------------------------------------------------- +FCB_LEN EQU 32 ; length of FCB +FCB_SHF EQU 5 +FN_LEN EQU 12 ; Length of filename in FCB + +FCB_DR EQU 0 ; Drive. 0 for default, 1-16 for A-P +FCB_FN EQU 1 ; Fn - Filename, 7-bit ASCII. The top bits - attributes +FCB_FT EQU 9 ; Filetype, 7-bit ASCII. + ; T1' to T3' have the following + ; T1' - Read-Only + ; T2' - System (hidden) + ; T3' - Archive +FCB_EXT EQU 12 ; EX - Set this to 0 when opening a file and then leave it to + ; CP/M. You can rewind a file by setting EX, RC, S2 and CR to 0. +FCB_S1 EQU 13 ; S1 - Reserved. +FCB_S2 EQU 14 ; S2 - Reserved. Bit 7 - wile write flag, [6:0] module number (Extent hi bits) +FCB_RC EQU 15 ; RC - Set this to 0 when opening a file and then leave it to CP/M. +FCB_AL EQU 16 ; AL - Image of the second half of the directory entry, + ; containing the file's allocation (which disc blocks it owns). +FCB_CR EQU 32 ; CR - Current record within extent. It is usually best to set + ; this to 0 immediately after a file has been opened and + ; then ignore it. +FCB_RN EQU 33 ; Rn - Random access record number. A 16-bit (with R2 used for overflow) + + +; ------------------------------------------------------ +JP_OPCODE EQU 0xC3 +; ------------------------------------------------------ +IRQ_0 EQU 0x01 +IRQ_1 EQU 0x02 +IRQ_2 EQU 0x04 +;LP_IRQ EQU 0x08 +KBD_IRQ EQU 0x02 + +KBD_ACK EQU 0x10 + +KEY_ALF EQU 0x0D +KEY_FIX EQU 0x15 +; ------------------------------------------------------ +LST_REC EQU 0x7F +; ------------------------------------------------------ +MAX_EXT EQU 0x1F +MAX_MOD EQU 0x0F +;MOD_NUM EQU 0x0E +; ------------------------------------------------------ +FCB_INFO_LEN EQU 15 ; length of FCB info bytes to match +;NXT_REC EQU 0x20 +; ------------------------------------------------------ +PIC_POLL_MODE EQU 0x0A +PORT_C4 EQU 0x10 +PRINTER_ACK EQU 0x10 +PRINTER_IRQ EQU 0x08 +; ------------------------------------------------------ +;RAN_REC EQU 0x21 +;FCB_RC EQU 0x0F +RO_FILE EQU 0x09 +ROM_CHIP_SIZE EQU 8192 ; ROM Size, used to limit monitor code size + +RX_READY EQU 0x02 +; ------------------------------------------------------ +TAPE_D EQU 0x08 +TAPE_P EQU 0x04 +TIMER_IRQ EQU 0x10 +TL_HIGH EQU 0x05 +TL_LOW EQU 0x03 +TL_MID EQU 0x04 +TMR0_SQWAVE EQU 0x36 +TRUE EQU 0xFF +TX_READY EQU 0x01 +; ------------------------------------------------------ + + ENDIF \ No newline at end of file diff --git a/MON_r8_bedc54ad/font-6x7.inc b/MON_r8_bedc54ad/font-6x7.inc new file mode 100644 index 0000000..221a101 --- /dev/null +++ b/MON_r8_bedc54ad/font-6x7.inc @@ -0,0 +1,165 @@ + ; 96 symbols 6x7, with codes 0x20..0x7f KOI-7 H0 +m_font_cp0: + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; ' ' - 0x20 + DB 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x04 ; '!' - 0x21 + DB 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00 ; '"' - 0x22 + DB 0x0a, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x0a ; '#' - 0x23 + DB 0x04, 0x1e, 0x05, 0x0e, 0x14, 0x0f, 0x04 ; '$' - 0x24 + DB 0x03, 0x13, 0x08, 0x04, 0x02, 0x19, 0x18 ; '%' - 0x25 + DB 0x06, 0x09, 0x05, 0x02, 0x15, 0x09, 0x16 ; '&' - 0x26 + DB 0x06, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00 ; ' - 0x27 + DB 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08 ; '(' - 0x28 + DB 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02 ; ')' - 0x29 + DB 0x00, 0x0a, 0x04, 0x1f, 0x04, 0x0a, 0x00 ; '*' - 0x2a + DB 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00 ; '+' - 0x2b + DB 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x02 ; ',' - 0x2c + DB 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00 ; '-' - 0x2d + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 ; '.' - 0x2e + DB 0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00 ; '/' - 0x2f + DB 0x0e, 0x11, 0x19, 0x15, 0x13, 0x11, 0x0e ; '0' - 0x30 + DB 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x0e ; '1' - 0x31 + DB 0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f ; '2' - 0x32 + DB 0x1f, 0x08, 0x04, 0x08, 0x10, 0x11, 0x0e ; '3' - 0x33 + DB 0x08, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x08 ; '4' - 0x34 + DB 0x1f, 0x01, 0x0f, 0x10, 0x10, 0x11, 0x0e ; '5' - 0x35 + DB 0x0c, 0x02, 0x01, 0x0f, 0x11, 0x11, 0x0e ; '6' - 0x36 + DB 0x1f, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02 ; '7' - 0x37 + DB 0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e ; '8' - 0x38 + DB 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x08, 0x06 ; '9' - 0x39 + DB 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00 ; ':' - 0x3a + DB 0x00, 0x06, 0x06, 0x00, 0x06, 0x04, 0x02 ; ';' - 0x3b + DB 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08 ; '<' - 0x3c + DB 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00 ; '=' - 0x3d + DB 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02 ; '>' - 0x3e + DB 0x0e, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04 ; '?' - 0x3f + DB 0x0e, 0x11, 0x10, 0x16, 0x15, 0x15, 0x0e ; '@' - 0x40 + DB 0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11 ; 'A' - 0x41 + DB 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f ; 'B' - 0x42 + DB 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e ; 'C' - 0x43 + DB 0x07, 0x09, 0x11, 0x11, 0x11, 0x09, 0x07 ; 'D' - 0x44 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f ; 'E' - 0x45 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01 ; 'F' - 0x46 + DB 0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x1e ; 'G' - 0x47 + DB 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 ; 'H' - 0x48 + DB 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e ; 'I' - 0x49 + DB 0x1c, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06 ; 'J' - 0x4a + DB 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 ; 'K' - 0x4b + DB 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f ; 'L' - 0x4c + DB 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11 ; 'M' - 0x4d + DB 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11 ; 'N' - 0x4e + DB 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; 'O' - 0x4f + DB 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01 ; 'P' - 0x50 + DB 0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16 ; 'Q' - 0x51 + DB 0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11 ; 'R' - 0x52 + DB 0x1e, 0x01, 0x01, 0x0e, 0x10, 0x10, 0x0f ; 'S' - 0x53 + DB 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; 'T' - 0x54 + DB 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; 'U' - 0x55 + DB 0x11, 0x11, 0x11, 0x11, 0x0a, 0x0a, 0x04 ; 'V' - 0x56 + DB 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a ; 'W' - 0x57 + DB 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 ; 'X' - 0x58 + DB 0x11, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04 ; 'Y' - 0x59 + DB 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f ; 'Z' - 0x5a + DB 0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e ; '[' - 0x5b + DB 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00 ; '\' - 0x5c + DB 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e ; ']' - 0x5d + DB 0x0e, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00 ; '^' - 0x5r + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f ; '_' - 0x5f + DB 0x1c, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00 ; '`' - 0x60 + DB 0x00, 0x00, 0x0e, 0x10, 0x1e, 0x13, 0x1e ; 'a' - 0x61 + DB 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x0f ; 'b' - 0x62 + DB 0x00, 0x00, 0x0e, 0x01, 0x01, 0x01, 0x0e ; 'c' - 0x63 + DB 0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x1e ; 'd' - 0x64 + DB 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e ; 'e' - 0x65 + DB 0x18, 0x04, 0x04, 0x0e, 0x04, 0x04, 0x04 ; 'f' - 0x66 + DB 0x00, 0x0e, 0x11, 0x11, 0x1e, 0x10, 0x0e ; 'g' - 0x67 + DB 0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x11 ; 'h' - 0x68 + DB 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04 ; 'i' - 0x69 + DB 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x06 ; 'j' - 0x6a + DB 0x01, 0x01, 0x09, 0x05, 0x03, 0x05, 0x09 ; 'k' - 0x6b + DB 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08 ; 'l' - 0x6c + DB 0x00, 0x00, 0x0f, 0x15, 0x15, 0x15, 0x15 ; 'm' - 0x6d + DB 0x00, 0x00, 0x09, 0x13, 0x11, 0x11, 0x11 ; 'n' - 0x6e + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e ; 'o' - 0x6f + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x0f, 0x01 ; 'p' - 0x70 + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x1e, 0x10 ; 'q' - 0x71 + DB 0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01 ; 'r' - 0x72 + DB 0x00, 0x00, 0x1e, 0x01, 0x0e, 0x10, 0x0f ; 's' - 0x73 + DB 0x04, 0x04, 0x0e, 0x04, 0x04, 0x04, 0x18 ; 't' - 0x74 + DB 0x00, 0x00, 0x11, 0x11, 0x11, 0x19, 0x16 ; 'u' - 0x75 + DB 0x00, 0x00, 0x11, 0x11, 0x0a, 0x0a, 0x04 ; 'v' - 0x76 + DB 0x00, 0x00, 0x11, 0x15, 0x15, 0x15, 0x0a ; 'w' - 0x77 + DB 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11 ; 'x' - 0x78 + DB 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0c ; 'y' - 0x79 + DB 0x00, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f ; 'z' - 0x7a + DB 0x0c, 0x02, 0x02, 0x01, 0x02, 0x02, 0x0c ; '{' - 0x7b + DB 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; '|' - 0x7c + DB 0x03, 0x04, 0x04, 0x08, 0x04, 0x04, 0x03 ; '}' - 0x7d + DB 0x00, 0x02, 0x15, 0x0a, 0x15, 0x08, 0x00 ; '~' - 0x7e + DB 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15 ; [DEL] - 0x7f + +; 64 symbols 6x7, with codes 0x40..0x7f KOI-7 H1 +m_font_cp1: + DB 0x00, 0x00, 0x09, 0x15, 0x17, 0x15, 0x09 ; ю - 0x40 + DB 0x00, 0x00, 0x06, 0x08, 0x0e, 0x09, 0x16 ; а - 0x41 + DB 0x07, 0x02, 0x04, 0x0e, 0x09, 0x09, 0x06 ; б - 0x42 DIFF + DB 0x00, 0x00, 0x09, 0x09, 0x09, 0x1f, 0x10 ; ц - 0x43 + DB 0x03, 0x04, 0x08, 0x0e, 0x09, 0x09, 0x06 ; д - 0x44 DIFF + DB 0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x1e ; е - 0x45 + DB 0x00, 0x04, 0x0e, 0x15, 0x15, 0x0e, 0x04 ; ф - 0x46 + DB 0x00, 0x00, 0x0f, 0x09, 0x01, 0x01, 0x01 ; г - 0x47 + DB 0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11 ; х - 0x48 + DB 0x00, 0x00, 0x11, 0x19, 0x15, 0x13, 0x11 ; и - 0x49 + DB 0x0a, 0x04, 0x11, 0x19, 0x15, 0x13, 0x11 ; й - 0x4a + DB 0x00, 0x00, 0x11, 0x09, 0x07, 0x09, 0x11 ; к - 0x4b + DB 0x00, 0x00, 0x1c, 0x12, 0x12, 0x12, 0x11 ; л - 0x4c + DB 0x00, 0x00, 0x11, 0x1b, 0x15, 0x11, 0x11 ; м - 0x4d + DB 0x00, 0x00, 0x11, 0x11, 0x1f, 0x11, 0x11 ; н - 0x4e + DB 0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e ; о - 0x4f + DB 0x00, 0x00, 0x1f, 0x11, 0x11, 0x11, 0x11 ; п - 0x50 + DB 0x00, 0x00, 0x1e, 0x11, 0x1e, 0x14, 0x12 ; я - 0x51 + DB 0x00, 0x00, 0x07, 0x09, 0x07, 0x01, 0x01 ; р - 0x52 + DB 0x00, 0x00, 0x0e, 0x01, 0x01, 0x01, 0x0e ; с - 0x53 + DB 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04 ; т - 0x54 + DB 0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0e ; у - 0x55 + DB 0x00, 0x00, 0x15, 0x15, 0x0e, 0x15, 0x15 ; ж - 0x56 + DB 0x00, 0x00, 0x03, 0x05, 0x07, 0x09, 0x07 ; в - 0x57 + DB 0x00, 0x00, 0x01, 0x01, 0x07, 0x09, 0x07 ; ь - 0x58 + DB 0x00, 0x00, 0x11, 0x11, 0x13, 0x15, 0x13 ; ы - 0x59 + DB 0x00, 0x00, 0x0e, 0x11, 0x0c, 0x11, 0x0e ; з - 0x5a + DB 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1f ; ш - 0x5b + DB 0x00, 0x00, 0x07, 0x08, 0x0e, 0x08, 0x07 ; э - 0x5c + DB 0x00, 0x00, 0x15, 0x15, 0x15, 0x1f, 0x10 ; щ - 0x5d + DB 0x00, 0x00, 0x09, 0x09, 0x0e, 0x08, 0x08 ; ч - 0x5e + DB 0x00, 0x00, 0x06, 0x05, 0x0c, 0x14, 0x0c ; ъ - 0x5f + DB 0x09, 0x15, 0x15, 0x17, 0x15, 0x15, 0x09 ; Ю - 0x60 + DB 0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11 ; А - 0x61 + DB 0x1f, 0x11, 0x01, 0x0f, 0x11, 0x11, 0x1f ; Б - 0x62 + DB 0x09, 0x09, 0x09, 0x09, 0x09, 0x1f, 0x10 ; С - 0x63 + DB 0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x1f, 0x11 ; Д - 0x64 + DB 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f ; Е - 0x65 + DB 0x04, 0x0e, 0x15, 0x15, 0x15, 0x0e, 0x04 ; Ф - 0x66 + DB 0x1f, 0x11, 0x01, 0x01, 0x01, 0x01, 0x01 ; Г - 0x67 + DB 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 ; Х - 0x68 + DB 0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11 ; И - 0x69 + DB 0x04, 0x15, 0x11, 0x19, 0x15, 0x13, 0x11 ; Й - 0x6a + DB 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 ; К - 0x6b + DB 0x1c, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11 ; Л - 0x6c + DB 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11 ; М - 0x6d + DB 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 ; Н - 0x6e + DB 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e ; О - 0x6f + DB 0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 ; П - 0x70 + DB 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x12, 0x11 ; Я - 0x71 + DB 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x01, 0x01 ; Р - 0x72 + DB 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e ; С - 0x73 + DB 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 ; Т - 0x74 + DB 0x11, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x0e ; У - 0x75 + DB 0x15, 0x15, 0x15, 0x0e, 0x15, 0x15, 0x15 ; Ж - 0x76 + DB 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f ; В - 0x77 + DB 0x01, 0x01, 0x01, 0x0f, 0x11, 0x11, 0x0f ; Ь - 0x78 + DB 0x11, 0x11, 0x11, 0x13, 0x15, 0x15, 0x13 ; Ы - 0x79 + DB 0x0e, 0x11, 0x10, 0x0c, 0x10, 0x11, 0x0e ; З - 0x7a + DB 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f ; Ш - 0x7b + DB 0x0e, 0x11, 0x10, 0x1c, 0x10, 0x11, 0x0e ; Э - 0x7c + DB 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x10 ; Щ - 0x7d + DB 0x11, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x10 ; Ч - 0x7e + DB 0x1f, 0x15, 0x1f, 0x15, 0x1f, 0x15, 0x1f ; [DEL] - 0x7f diff --git a/MON_r8_bedc54ad/io.inc b/MON_r8_bedc54ad/io.inc new file mode 100644 index 0000000..d884e0b --- /dev/null +++ b/MON_r8_bedc54ad/io.inc @@ -0,0 +1,132 @@ +; ======================================================= +; Ocean-240.2 +; Computer with FDC variant. +; IO Ports definitions +; +; By Romych 2025-09-09 +; ======================================================= + + IFNDEF _IO_PORTS + DEFINE _IO_PORTS + +; ------------------------------------------------------- +; КР580ВВ55 DD79 +; ------------------------------------------------------- +; Port A - User port A +USR_DD79PA EQU 0x00 + +; Port B - User port B +USR_DD79PB EQU 0x01 + +; Port C - User port C +USR_DD79PC EQU 0x02 + +; Config: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1] +USR_DD79CTR EQU 0x03 + +; ------------------------------------------------------- +; КР1818ВГ93 +; ------------------------------------------------------- +; CMD +FDC_CMD EQU 0x20 + +; TRACK +FDC_TRACK EQU 0x21 + +; SECTOR +FDC_SECT EQU 0x22 + +; DATA +FDC_DATA EQU 0x23 + +; +FDC_WAIT EQU 0x24 + +; Controller port +FLOPPY EQU 0x25 + + +; ------------------------------------------------------- +; КР580ВВ55 DD78 +; ------------------------------------------------------- +; Port A - Keyboard Data +KBD_DD78PA EQU 0x40 + +; Port B - JST3,SHFT,CTRL,ACK,TAPE5,TAPE4,GK,GC +KBD_DD78PB EQU 0x41 + +; Port C - [PC7..0] +KBD_DD78PC EQU 0x42 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +KBD_DD78CTR EQU 0x43 + + +; ------------------------------------------------------- +; КР580ВИ53 DD70 +; ------------------------------------------------------- +; Counter 1 +TMR_DD70C1 EQU 0x60 + +; Counter 2 +TMR_DD70C2 EQU 0x61 + +; Counter 3 +TMR_DD70C3 EQU 0x62 + +; Config: [sc1,sc0][rl1,rl0][m2,m1,m0][bcd] +; sc - timer, rl=01-LSB, 10-MSB, 11-LSB+MSB +; mode 000 - int on fin, +; 001 - one shot, +; x10 - rate gen, +; x11-sq wave +TMR_DD70CTR EQU 0x63 + +; Programable Interrupt controller PIC KR580VV59 +PIC_DD75RS EQU 0x80 +PIC_DD75RM EQU 0x81 + +; ------------------------------------------------------- +; КР580ВВ51 DD72 +; ------------------------------------------------------- +; Data +UART_DD72RD EQU 0xA0 + +; [RST,RQ_RX,RST_ERR,PAUSE,RX_EN,RX_RDY,TX_RDY] +UART_DD72RR EQU 0xA1 + +; ------------------------------------------------------- +; КР580ВВ55 DD17 +; ------------------------------------------------------- +; Port A - VShift[8..1] +SYS_DD17PA EQU 0xC0 + +; Port B - [ROM14,13][REST][ENROM-][A18,17,16][32k] +SYS_DD17PB EQU 0xC1 + +; Port C - HShift[HS5..1,SB3..1] +SYS_DD17PC EQU 0xC2 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +SYS_DD17CTR EQU 0xC3 + +; ------------------------------------------------------- +; КР580ВВ55 DD67 +; ------------------------------------------------------- +; Port A - LPT Data +LPT_DD67PA EQU 0xE0 + +; Port B - [VSU,C/M,FL3..1,COL3..1] +VID_DD67PB EQU 0xE1 + +; Port C - [USER3..1,STB-LP,BELL,TAPE3..1] +DD67PC EQU 0xE2 + +; Сonfig: [1][ma1,ma0][0-aO|1-aI],[0-chO,1-chI],[mb],[0-bO|1-bI],[0-clO,1-clI] +; Set bit: [0][xxx][bbb][0|1]; +DD67CTR EQU 0xE3 + + ENDIF \ No newline at end of file diff --git a/MON_r8_bedc54ad/m_vars.inc b/MON_r8_bedc54ad/m_vars.inc new file mode 100644 index 0000000..578bddd --- /dev/null +++ b/MON_r8_bedc54ad/m_vars.inc @@ -0,0 +1,101 @@ +; ======================================================= +; Ocean-240.2 +; Module M_VARS - Monitor variables +; RAM Range: 0xBA09-0xBFFF +; +; Disassembled by Romych 2025-02-05 +; ======================================================= + + IFNDEF _M_VARS + DEFINE _M_VARS + + MODULE M_VARS + ORG 0xbf00 + +buffer DS 128 ; 0xbf00 search text or buffer to search? + DS 36 +paint_stack EQU $ ; 0xbfa4 + DS 32 +stack1: EQU $ ; 0xbfc4 + DS 1 +paint_var1 DS 1 ; 0xbfc5 +paint_var2 DS 1 ; 0xbfc6 +paint_var3 DS 1 ; 0xbfc7 +paint_var4 DS 1 ; 0xbfc8 +paint_var5 DS 1 ; 0xbfc9 +paint_y DS 1 ; 0xbfca +paint_var7 DS 1 ; 0xbfcb +cmp_color DS 1 ; 0xbfcc +paint_sp_save DS 2 + +; Right pixel mask ex: 11111000 +pixel_mask_r DS 1 ; 0xbfcf +tmp_color DS 1 ; 0xbfd0 +rect_var2 DS 1 ; 0xbfd1 +stack_0 EQU $ +rect_var3 DS 1 ; 0xbfd2 +esc_mode DS 1 ; 0xbfd3 +esc_cmd DS 1 ; 0xbfd4 + +esc_param_cnt DS 1 ; 0xbfd5 +esc_param DS 7 ; 0xbfd6 + +; Left inverse pixel mask ex: 00011111 +pixel_mask_l_i DS 1 +; Right inverse pixel mask ex: 00011111 +pixel_mask_r_i DS 1 +; Left pixel mask ex: 11100000 +pixel_mask_l DS 1 + +; Current screen mode, bit 3 - hide/show cursor, bit 4 - only 20 rows +screen_mode DS 1 ; 0xbfe0 +cursor_row DS 1 ; 0xbfe1 Cursor Y position +cursor_col DS 1 ; 0xbfe2 Cursor X position +curr_color DS 2 ; 0xbfe3 Current color low and hi bytes +esc_hex_cmd: +row_shift DS 1 ; 0xbfe5 +codepage DS 1 ; 0xbfe6 + + +cur_palette DS 1 ; 0xbfe7 00bbbfff - background and foreground colors +beep_period DS 2 ; 0xbfe8 +beep_duration DS 2 ; 0xbfea +pix_shift DS 1 ; 0xbfec +strobe_state DS 1 ; 0xbfed +ul_var0 DS 1 ; 0xbfee +ul_A_var1 DS 1 ; 0xbfef +ul_B_var2 DS 1 ; 0xbff0 +ul_var3 DS 1 ; 0xbff1 +ul_A_var4 DS 1 ; 0xbff2 +ul_B_var5 DS 1 ; 0xbff3 +ul_var6 DS 1 ; 0xbff4 +esc_var0 DS 1 ; 0xbff5 +esc_var1 DS 1 ; 0xbff6 +esc_var2 DS 1 ; 0xbff7 +esc_var3 DS 1 ; 0xbff8 + DS 1 ; 0xbff9 + DS 1 ; 0xbffa + DS 1 ; 0xbffb + DS 1 ; 0xbffc + DS 1 ; 0xbffd + DS 1 ; 0xbffe + DS 1 ; 0xbfff + + ASSERT stack1 = 0xbfc4 + ASSERT buffer = 0xbf00 + ASSERT paint_var1 = 0xbfc5 + ASSERT pixel_mask_r = 0xbfcf + ASSERT stack_0 = 0xbfd2 + ASSERT esc_mode = 0xbfd3 + ASSERT screen_mode = 0xbfe0 + ASSERT cur_palette = 0xbfe7 + ASSERT ul_var0 = 0xbfee + ASSERT paint_stack = 0xbfa4 + ASSERT esc_var3 = 0xbff8 + + ;DISPLAY "screen_mode: ", /H, screen_mode + ;DISPLAY "fn48_var1: ", /H, fn48_var1 + + ENDMODULE + + ENDIF diff --git a/MON_r8_bedc54ad/mon_only.map b/MON_r8_bedc54ad/mon_only.map new file mode 100644 index 0000000..1ccd518 --- /dev/null +++ b/MON_r8_bedc54ad/mon_only.map @@ -0,0 +1,449 @@ +MONITOR.start 0xe000 f +MONITOR.mon_hexb 0xe003 f +MONITOR.non_con_status 0xe006 f +MONITOR.mon_con_in 0xe009 f +MONITOR.mon_con_out 0xe00c f +MONITOR.mon_serial_in 0xe00f f +MONITOR.mon_serial_out 0xe012 f +MONITOR.mon_char_print 0xe015 f +MONITOR.mon_tape_read 0xe018 f +MONITOR.mon_tape_write 0xe01b f +MONITOR.ram_disk_read 0xe01e f +MONITOR.ram_disk_write 0xe021 f +MONITOR.mon_tape_read_ram 0xe024 f +MONITOR.mon_tape_write_ram 0xe027 f +MONITOR.mon_tape_wait 0xe02a f +MONITOR.mon_tape_detect 0xe02d f +MONITOR.read_floppy 0xe030 f +MONITOR.write_floppy 0xe033 f +MONITOR.mon_out_str_z 0xe036 f +MONITOR.m_hot_start 0xe051 f +MONITOR.m_hot_start.fill_video 0xe06c f +MONITOR.m_hot_start.conf_uart 0xe0a7 f +MONITOR.m_hot_start.conf_pic 0xe0ba f +MONITOR.m_out_strz 0xe0f1 f +MONITOR.mgs_system_nf 0xe0fc f +MONITOR.m_sys_halt 0xe111 f +MONITOR.m_con_status 0xe112 f +MONITOR.m_serial_in 0xe11c f +MONITOR.m_con_in 0xe128 f +MONITOR.m_serial_out 0xe13d f +MONITOR.m_char_print 0xe148 f +MONITOR.m_char_print.wait_lp 0xe157 f +MONITOR.m_con_out 0xe163 f +MONITOR.m_con_out_int 0xe16d f +MONITOR.get_esc_param 0xe187 f +MONITOR.esc_no_draw_fn 0xe1c1 f +MONITOR.esc_exit 0xe1c6 f +MONITOR.esc_params_tab 0xe1cb f +MONITOR.esc_handler_tab 0xe1db f +MONITOR.esc_set_beep 0xe1f9 f +MONITOR.esc_set_cursor2 0xe20e f +MONITOR.esc_print_screen 0xe211 f +MONITOR.esc_print_screen.chk_keys 0xe220 f +MONITOR.esc_print_screen.no_keys 0xe22d f +MONITOR.m_print_hor_line 0xe23a f +MONITOR.m_print_hor_line.print_next_col 0xe248 f +MONITOR.m_print_cmd 0xe276 f +MONITOR.m_print_cmd.print_nxt 0xe277 f +MONITOR.m_print_cmd.cmd_end 0xe285 f +MONITOR.m_print_vert_7pix 0xe287 f +MONITOR.cmd_esc_inc_Y2 0xe2a5 f +MONITOR.cmd_esc_set_X0 0xe2a9 f +MONITOR.cmd_esc_set_X 0xe2ae f +MONITOR.cmd_esc_print_col 0xe2b1 f +MONITOR.m_get_7vpix 0xe2b4 f +MONITOR.m_get_7vpix.calc_pix_no 0xe2be f +MONITOR.m_get_7vpix.for_all_pix 0xe2dc f +MONITOR.m_get_7vpix.all_shifted 0xe2e9 f +MONITOR.m_get_7vpix.not_1_1 0xe2f2 f +MONITOR.m_get_7vpix.not_1_2 0xe2fa f +MONITOR.esc_set_palette 0xe2fe f +MONITOR.esp_no_colr 0xe313 f +MONITOR.esc_set_charset 0xe317 f +MONITOR.m_get_glyph 0xe320 f +MONITOR.m_get_glyph.cp_rus 0xe340 f +MONITOR.m_get_glyph.cp_common 0xe344 f +MONITOR.m_print_no_esc 0xe349 f +MONITOR.m_print_no_esc.l1 0xe377 f +MONITOR.m_print_no_esc.l2 0xe381 f +MONITOR.m_print_no_esc.l3 0xe389 f +MONITOR.m_print_no_esc.l4 0xe391 f +MONITOR.m_print_no_esc.l5 0xe396 f +MONITOR.m_print_no_esc.sym_draw 0xe39a f +MONITOR.m_print_no_esc.pne_l7 0xe3a5 f +MONITOR.m_print_no_esc.pne_l8 0xe3aa f +MONITOR.m40_rt 0xe3ee f +MONITOR.m40_wrap_rt 0xe3f9 f +MONITOR.m40_lf 0xe405 f +MONITOR.m40_bksp 0xe40f f +MONITOR.m40_bksp.wrap 0xe41d f +MONITOR.m40_up 0xe421 f +MONITOR.m40_up.up_no_minus 0xe429 f +MONITOR.m20_tab 0xe42b f +MONITOR.calc_addr_40 0xe439 f +MONITOR.calc_addr_40.l1 0xe454 f +MONITOR.calc_addr_40.l2 0xe45a f +MONITOR.m2_lf 0xe464 f +MONITOR.m2_lf.lf_nowr 0xe46e f +MONITOR.m2_lf.cas_l5 0xe47b f +MONITOR.m2_lf.cas_l6 0xe480 f +MONITOR.m2_lf.cas_l7 0xe496 f +MONITOR.m2_lf.cas_l8 0xe49b f +MONITOR.m20_bksp 0xe4ab f +MONITOR.mp_mode_64 0xe4b8 f +MONITOR.mp_mode_64.next_row 0xe4d3 f +MONITOR.m64_rt 0xe4e7 f +MONITOR.m64_lf 0xe4f0 f +MONITOR.scroll_up 0xe4fa f +MONITOR.scroll_up.next_row 0xe512 f +MONITOR.scroll_up.next_col 0xe514 f +MONITOR.m64_bs 0xe524 f +MONITOR.m64_up 0xe52f f +MONITOR.m64_up.no_wrap 0xe537 f +MONITOR.m64_tab 0xe539 f +MONITOR.mp_mode_80 0xe545 f +MONITOR.mp_mode_80.l1 0xe55e f +MONITOR.mp_mode_80.l2 0xe56d f +MONITOR.mp_mode_80.l3 0xe58e f +MONITOR.mp_mode_80.l4 0xe5b3 f +MONITOR.mp_mode_80.l5 0xe5b4 f +MONITOR.mp_mode_80.l6 0xe5c4 f +MONITOR.m80_rt 0xe5cf f +MONITOR.m80_col_wrap 0xe5da f +MONITOR.m80_lf 0xe5de f +MONITOR.m80_bs 0xe5e8 f +MONITOR.m80_bs.wrap 0xe5f6 f +MONITOR.m80_up 0xe5fa f +MONITOR.m80_up.no_wrap 0xe602 f +MONITOR.m80_tab 0xe604 f +MONITOR.calc_addr_80 0xe612 f +MONITOR.mns_l1 0xe62d f +MONITOR.mns_ep_fm_0 0xe633 f +MONITOR.m_clear_screen 0xe639 f +MONITOR.m_clear_screen.fill_scrn 0xe652 f +MONITOR.m_clear_screen.mono_mode 0xe669 f +MONITOR.m_cursor_home 0xe66c f +MONITOR.m_clear_20_rows 0xe679 f +MONITOR.m_clear_20_rows.next_row 0xe683 f +MONITOR.m_clear_20_rows.next_col 0xe688 f +MONITOR.m_draw_cursor 0xe69a f +MONITOR.m_draw_cursor.dc_rt2 0xe6cf f +MONITOR.m_draw_cursor.dc_mid 0xe6d7 f +MONITOR.m_draw_cursor.dc_lt 0xe6dd f +MONITOR.m_draw_cursor.dc_rt1 0xe6e3 f +MONITOR.m_draw_cursor.dc_put 0xe6e6 f +MONITOR.m_draw_cursor.dc_mode_64 0xe703 f +MONITOR.m_draw_cursor.cur_64_next 0xe721 f +MONITOR.m_draw_cursor.dc_mode_80 0xe72f f +MONITOR.m_draw_cursor.dc_1_byte 0xe75e f +MONITOR.m_draw_cursor.dc_2_byte 0xe769 f +MONITOR.m_draw_cursor.dc_80_end 0xe776 f +MONITOR.m_handle_esc_code 0xe77c f +MONITOR.m_handle_control_code 0xe78a f +MONITOR.handle_cc_common 0xe7c4 f +MONITOR.handle_cc_common.handle_cc_mono 0xe7ff f +MONITOR.handle_cc_80x25 0xe833 f +MONITOR.m_beep 0xe85a f +MONITOR.m_bell_cont 0xe86f f +MONITOR.m_bell_wait_tmr1 0xe879 f +MONITOR.m_bell_wait_tmr2 0xe886 f +MONITOR.esc_set_cursor 0xe890 f +MONITOR.esc_set_cursor.mode_40 0xe8bf f +MONITOR.esc_set_cursor.mode_80 0xe8ca f +MONITOR.esc_set_cursor.common 0xe8d2 f +MONITOR.esc_le_24 0xe8df f +MONITOR.esc_set_vmode 0xe8e9 f +MONITOR.esc_set_vmode.set_color_mode 0xe90f f +MONITOR.esc_set_vmode.skip_for_mono_mode 0xe911 f +MONITOR.esc_set_vmode.draw_cursor 0xe91a f +MONITOR.esc_set_vmode.cursor_hide 0xe91e f +MONITOR.esc_set_vmode.cursor_show 0xe928 f +MONITOR.esc_set_color 0xe92f f +MONITOR.m_set_color 0xe932 f +MONITOR.m_print_at_xy 0xe943 f +MONITOR.m_print_at_xy.mode_sp 0xe986 f +MONITOR.m_print_at_xy.out_sp 0xe99b f +MONITOR.m_print_at_xy.next_line 0xe9a2 f +MONITOR.m_print_at_xy.l04 0xe9af f +MONITOR.m_print_at_xy.l05 0xe9b4 f +MONITOR.m_print_at_xy.sprites_en 0xe9e2 f +MONITOR.mode2_exit 0xe9e6 f +MONITOR.co_ex_l08 0xe9ed f +MONITOR.out_no_xor 0xe9f1 f +MONITOR.out_no_xor.l10 0xe9fe f +MONITOR.out_no_xor.l11 0xea03 f +MONITOR.game_sprite_tab 0xea39 f +MONITOR.calc_px_addr 0xeb51 f +MONITOR.esc_draw_fill_rect 0xeb64 f +MONITOR.esc_draw_fill_rect.non_zero_h 0xeb73 f +MONITOR.esc_draw_fill_rect.shift_mask_l 0xeb78 f +MONITOR.esc_draw_fill_rect.shift_mask_r 0xeb8d f +MONITOR.esc_draw_fill_rect.next_line 0xebb7 f +MONITOR.esc_draw_fill_rect.rectangle_xor 0xebc6 f +MONITOR.esc_draw_fill_rect.edf_l6 0xebd5 f +MONITOR.esc_draw_fill_rect.next_8px 0xebdf f +MONITOR.esc_draw_fill_rect.w_ne_0 0xebe0 f +MONITOR.esc_draw_fill_rect.r_mask 0xebf6 f +MONITOR.esc_draw_fill_rect.next_full 0xebfc f +MONITOR.esc_draw_fill_rect.complete 0xec0b f +MONITOR.esc_paint 0xec18 f +MONITOR.esc_paint.l1 0xec57 f +MONITOR.ep_fm_0 0xec8b f +MONITOR.ep_task_end 0xec9a f +MONITOR.ep_l4 0xecb5 f +MONITOR.ep_l5 0xecbd f +MONITOR.ep_l6 0xecc5 f +MONITOR.ep_f_fast 0xecd7 f +MONITOR.ep_l8 0xece5 f +MONITOR.ep_l9 0xed1d f +MONITOR.ep_l10 0xed2c f +MONITOR.ep_l11 0xed3d f +MONITOR.paint_find_next_right 0xed77 f +MONITOR.paint_find_next_right.l1 0xed84 f +MONITOR.paint_find_next_right.l2 0xed90 f +MONITOR.paint_find_next_left 0xed9a f +MONITOR.paint_find_next_left.l1 0xeda7 f +MONITOR.paint_find_next_left.l2 0xedb3 f +MONITOR.ep_l12 0xedbd f +MONITOR.ep_l13 0xedd6 f +MONITOR.ep_l14 0xede8 f +MONITOR.ep_l15 0xedf1 f +MONITOR.ep_l16 0xedfa f +MONITOR.paint_find_right 0xedfd f +MONITOR.paint_find_right.in_byte 0xee0a f +MONITOR.paint_find_left 0xee18 f +MONITOR.paint_find_left.in_byte 0xee24 f +MONITOR.get_pixel 0xee32 f +MONITOR.get_pixel.bit1_set 0xee48 f +MONITOR.get_pixel.bit2_set 0xee57 f +MONITOR.get_pixel.bit12_set 0xee5f f +MONITOR.paint_task 0xee67 f +MONITOR.paint_task.lmp_mask 0xee7e f +MONITOR.paint_task.rmp_mask 0xee97 f +MONITOR.paint_task.lmi_mask 0xeea3 f +MONITOR.paint_task.rmi_mask 0xeeac f +MONITOR.paint_exit 0xeec6 f +MONITOR.draw_line_h 0xeed1 f +MONITOR.draw_line_h.next_byte 0xeedc f +MONITOR.draw_line_h.width_ne0 0xeedd f +MONITOR.draw_line_h.r_mask 0xeef5 f +MONITOR.draw_line_h.full_8 0xeefb f +MONITOR.draw_line_h.complete 0xef06 f +MONITOR.esc_draw_line 0xef0b f +MONITOR.esc_draw_line.x1_le_x2 0xef1b f +MONITOR.esc_draw_line.pos_height 0xef2b f +MONITOR.esc_draw_line.next_16 0xef45 f +MONITOR.esc_draw_line.edl_l4 0xef51 f +MONITOR.esc_draw_line.edl_l5 0xef54 f +MONITOR.esc_draw_line.roll_l 0xef67 f +MONITOR.esc_draw_line.edl_l7 0xef6e f +MONITOR.esc_draw_line.next_up 0xef89 f +MONITOR.esc_draw_line.next_down 0xef9f f +MONITOR.esc_draw_line.is_last 0xefb5 f +MONITOR.esc_draw_line.edl_l11 0xefc3 f +MONITOR.esc_draw_line.width0 0xefcb f +MONITOR.esc_draw_line.edl_l13 0xefd1 f +MONITOR.esc_draw_line.next_row_up 0xefe5 f +MONITOR.esc_draw_line.next_row_down 0xeffb f +MONITOR.close_vram_ret 0xf011 f +MONITOR.height0 0xf016 f +MONITOR.height0.len_ne0 0xf01e f +MONITOR.height0.edl_l19 0xf023 f +MONITOR.height0.next_col 0xf033 f +MONITOR.height0.edl_l21 0xf048 f +MONITOR.esc_draw_dot 0xf052 f +MONITOR.edd_l1 0xf05b f +MONITOR.edd_ep_fm_0 0xf084 f +MONITOR.edd_ep_task_end 0xf09d f +MONITOR.esc_picture 0xf0a4 f +MONITOR.pict_sub1 0xf0d6 f +MONITOR.pict_clr 0xf0f3 f +MONITOR.ehd_l1 0xf104 f +MONITOR.m_fn_39 0xf10f f +MONITOR.m_fn_39.l1 0xf12e f +MONITOR.m_fn_39.l2 0xf148 f +MONITOR.m_fn_39.l3 0xf15f f +MONITOR.get_image_hdr 0xf177 f +MONITOR.esc_get_put_image 0xf1b5 f +MONITOR.get_image 0xf1e1 f +MONITOR.get_image.next_row 0xf1e3 f +MONITOR.get_image.l2 0xf1f2 f +MONITOR.put_image 0xf201 f +MONITOR.put_image.next_row 0xf203 f +MONITOR.put_image.l2 0xf213 f +MONITOR.img_task_end 0xf21e f +MONITOR.fn39_sub2 0xf223 f +MONITOR.fn39_sub2.l1 0xf224 f +MONITOR.fn39_sub2.l2 0xf225 f +MONITOR.fn39_sub2.l3 0xf233 f +MONITOR.fn39_sub2.l4 0xf238 f +MONITOR.fn39_sub2.l5 0xf245 f +MONITOR.fn39_sub2.l6 0xf24a f +MONITOR.gih_rt 0xf266 f +MONITOR.gih_rt.l1 0xf289 f +MONITOR.gih_rt.l2 0xf28d f +MONITOR.gih_rt.l3 0xf291 f +MONITOR.gih_bs 0xf2bd f +MONITOR.gih_bs.l1 0xf2dd f +MONITOR.gih_bs.l2 0xf2e9 f +MONITOR.gih_bs.l3 0xf2ed f +MONITOR.gih_ctrl_z 0xf319 f +MONITOR.gih_ctrl_z.l1 0xf32e f +MONITOR.gih_ctrl_z.l2 0xf332 f +MONITOR.gih_ctrl_z.l3 0xf345 f +MONITOR.gih_ctrl_z.l4 0xf34a f +MONITOR.gih_ctrl_z.l5 0xf35a f +MONITOR.gih_up 0xf368 f +MONITOR.gih_up.l1 0xf378 f +MONITOR.gih_up.l2 0xf390 f +MONITOR.gih_up.l3 0xf394 f +MONITOR.gih_up.l4 0xf3a7 f +MONITOR.gih_up.l5 0xf3ac f +MONITOR.gih_up.l6 0xf3bc f +MONITOR.pict_sub2 0xf3ca f +MONITOR.pict_sub2.l1 0xf3f2 f +MONITOR.pict_sub2.l2 0xf3f7 f +MONITOR.pict_sub2.l3 0xf3fb f +MONITOR.pict_sub2.l4 0xf426 f +MONITOR.mov_hl_bc 0xf43b f +MONITOR.mov_hl_bc.next 0xf442 f +MONITOR.esc_draw_circle 0xf44c f +MONITOR.esc_draw_circle.l1 0xf469 f +MONITOR.esc_draw_circle.l2 0xf480 f +MONITOR.esc_draw_circle.l3 0xf4a2 f +MONITOR.dc_draw_8px 0xf4ab f +MONITOR.dc_aspect_ratio_1 0xf4c7 f +MONITOR.dc_aspect_ratio_1.dc_ax_ne0 0xf4d7 f +MONITOR.dc_aspect_ratio_1.dc_ay_ne0 0xf4e0 f +MONITOR.dc_aspect_ratio2 0xf4e7 f +MONITOR.dc_aspect_ratio2.dc_ax_ne0 0xf4f7 f +MONITOR.dc_aspect_ratio2.dc_ay_ne0 0xf500 f +MONITOR.dc_mul_e_h 0xf507 f +MONITOR.dc_mul_e_h.l1 0xf50f f +MONITOR.dc_mul_e_h.l2 0xf514 f +MONITOR.dc_mul_e_h.l3 0xf519 f +MONITOR.dc_mul_e_h.l4 0xf51e f +MONITOR.dc_mul_e_h.l5 0xf523 f +MONITOR.dc_mul_e_h.l6 0xf528 f +MONITOR.dc_mul_e_h.l7 0xf52d f +MONITOR.dc_mul_e_h.l8 0xf532 f +MONITOR.dc_draw_4px_bc 0xf534 f +MONITOR.dc_draw_4px_bc.l1 0xf540 f +MONITOR.dc_draw_4px_bc.l2 0xf54c f +MONITOR.dc_draw_4px_bc.l3 0xf558 f +MONITOR.dc_draw_4px_cb 0xf563 f +MONITOR.dc_draw_4px_cb.l1 0xf56f f +MONITOR.dc_draw_4px_cb.l2 0xf57b f +MONITOR.l3 0xf587 f +MONITOR.dc_put_pixel 0xf592 f +MONITOR.dc_put_pixel.roll 0xf59a f +MONITOR.m_font_cp0 0xf5bc f +MONITOR.m_font_cp1 0xf85c f +MONITOR.conv_nibble 0xfa1c f +MONITOR.m_hexb 0xfa26 f +MONITOR.out_hex 0xfa2f f +MONITOR.m_tape_write_ram2 0xfa36 f +MONITOR.m_tape_write_ram2.cl_stack 0xfa3b f +MONITOR.m_tape_write_ram2.nxt_blk 0xfa5d f +MONITOR.twr2_delay 0xfa73 f +MONITOR.twr2_delay.delay 0xfa76 f +MONITOR.m_tape_read_ram2 0xfa7d f +MONITOR.m_tape_read_ram2.srch_first 0xfa88 f +MONITOR.m_tape_read_ram2.rd_next 0xfaa6 f +MONITOR.m_tape_read_ram2.not_found 0xfac5 f +MONITOR.m_tape_read_ram2.rd_error 0xfacc f +MONITOR.m_tape_read_ram2.inv_id 0xfae1 f +MONITOR.m_tape_read_ram2.err_ubi 0xfaed f +MONITOR.m_tape_read_ram2.err_ibu 0xfaf5 f +MONITOR.m_tape_read_ram2.end 0xfaf6 f +MONITOR.out_hexw 0xfafd f +MONITOR.msg_no_start_rec 0xfb08 f +MONITOR.msg_checksum 0xfb18 f +MONITOR.msg_sequence 0xfb22 f +MONITOR.msg_ibg 0xfb2c f +MONITOR.msg_break 0xfb30 f +MONITOR.me_out_strz 0xfb36 f +MONITOR.m_ramdisk_read 0xfb43 f +MONITOR.m_ramdisk_read.read 0xfb55 f +MONITOR.m_ramdisk_write 0xfb6d f +MONITOR.m_ramdisk_write.wr_byte 0xfb7f f +MONITOR.m_tape_write 0xfb97 f +MONITOR.m_tape_write.l1 0xfbae f +MONITOR.m_tape_write.set_lvl 0xfbc0 f +MONITOR.m_tape_write.l2 0xfbd0 f +MONITOR.m_tape_write.next_byte 0xfbee f +MONITOR.m_tape_write.wait_end 0xfc00 f +MONITOR.m_tape_wr_byte 0xfc0e f +MONITOR.m_tape_wr_byte.get_bit 0xfc15 f +MONITOR.m_tape_wr_byte.wait_t 0xfc1b f +MONITOR.m_tape_wr_byte.out_bit 0xfc39 f +MONITOR.m_tape_wr_byte.bit_hi 0xfc41 f +MONITOR.m_tape_wr_byte.out_bit_hi 0xfc5f f +MONITOR.m_tape_read 0xfc67 f +MONITOR.m_tape_read.wait_3_changes 0xfc79 f +MONITOR.m_tape_read.wait_4th_change 0xfc8a f +MONITOR.m_tape_read.wait_f5_marker 0xfc99 f +MONITOR.m_tape_read.read_next_b 0xfcbd f +MONITOR.m_tape_read.checksum_ok 0xfcd6 f +MONITOR.m_tape_read.return 0xfcd7 f +MONITOR.m_tape_read.err_read_blk 0xfcda f +MONITOR.m_tape_read.err_read_id 0xfcde f +MONITOR.m_tape_read.key_pressed 0xfce3 f +MONITOR.m_tape_read_byte 0xfcee f +MONITOR.m_tape_read_byte.next_bit 0xfcf1 f +MONITOR.m_tape_read_byte.ret_err 0xfd06 f +MONITOR.m_read_tape_bit 0xfd08 f +MONITOR.m_read_tape_bit.wait_change 0xfd0d f +MONITOR.read_tape_bit_kbd 0xfd2b f +MONITOR.read_tape_bit_kbd.wait_change 0xfd30 f +MONITOR.read_tape_bit_kbd.key_pressed 0xfd55 f +MONITOR.m_tape_wait 0xfd58 f +MONITOR.m_tape_wait.wait_t4 0xfd5c f +MONITOR.m_tape_wait.wait_next_2ms 0xfd62 f +MONITOR.m_tape_wait.wait_tmr_key 0xfd6d f +MONITOR.m_tape_wait.wait_no_rst4 0xfd86 f +MONITOR.m_tape_wait.key_pressed 0xfd8d f +MONITOR.m_tape_blk_detect 0xfd95 f +MONITOR.fdc_unload_head 0xfd9e f +MONITOR.fdc_unload_head.wait_no_busy 0xfda8 f +MONITOR.fdc_unload_head.tr0_ok 0xfdba f +MONITOR.fdc_unload_head.b1 0xfdc9 f +MONITOR.m_select_drive 0xfdd1 f +MONITOR.m_select_drive.sel_A 0xfddf f +MONITOR.m_select_drive.sel_B 0xfde1 f +MONITOR.m_select_drive.dpar_a 0xfdf6 f +MONITOR.m_select_drive.dpar_b 0xfdf9 f +MONITOR.m_select_drive.l_le 0xfe15 f +MONITOR.delay_136uS 0xfe24 f +MONITOR.delay_b 0xfe26 f +MONITOR.delay_1.4mS 0xfe2b f +MONITOR.m_read_floppy 0xfe30 f +MONITOR.m_write_floppy 0xfe43 f +MONITOR.m_start_seek_track 0xfe56 f +MONITOR.m_start_floppy 0xfe5f f +MONITOR.m_start_floppy.need_m_start 0xfe6b f +MONITOR.m_start_floppy.wait_motor 0xfe76 f +MONITOR.m_start_floppy.wait_rdy1 0xfe7d f +MONITOR.m_start_floppy.long_delay 0xfe8f f +MONITOR.m_start_floppy.mst_exi 0xfe95 f +MONITOR.fdc_init 0xfe97 f +MONITOR.m_fdc_seek_trk 0xfea3 f +MONITOR.m_fdc_seek_trk.drv_b 0xfebc f +MONITOR.m_fdc_seek_trk.cmn 0xfecd f +MONITOR.m_fdc_seek_trk.l1 0xfef5 f +MONITOR.m_fdc_seek_trk.l2 0xff06 f +MONITOR.m_fdc_seek_trk.l3 0xff1d f +MONITOR.m_fdc_seek_trk.l4 0xff20 f +MONITOR.m_fdc_write_bytes 0xff26 f +MONITOR.m_fdc_write_bytes.w_next 0xff29 f +MONITOR.m_fdc_read_c_bytes 0xff37 f +MONITOR.m_fdc_read_c_bytes.l1 0xff3d f +MONITOR.m_fdc_read_c_bytes.l2 0xff3f f +MONITOR.fdc_check_status 0xff4b f +MONITOR.fdc_ret 0xff55 f +MONITOR.filler1 0xff56 f +MONITOR.LAST 0xff57 l +MONITOR.CODE_SIZE 0x1f57 l +MONITOR.FILL_SIZE 0xa9 l +MONITOR.FILLER 0xff57 f diff --git a/MON_r8_bedc54ad/monitor.asm b/MON_r8_bedc54ad/monitor.asm new file mode 100644 index 0000000..d989df3 --- /dev/null +++ b/MON_r8_bedc54ad/monitor.asm @@ -0,0 +1,5597 @@ +; ====================================================== +; Ocean-240.2 +; Monitor V8 +; crc32: bedc54ad +; +; Disassembled by Romych 2026-02-17 +; ====================================================== + + DEVICE NOSLOT64K + + INCLUDE "io.inc" + INCLUDE "equates.inc" + INCLUDE "ram.inc" + INCLUDE "bios_entries.inc" + + OUTPUT monitor_E000.bin + + + MODULE MONITOR + + ORG 0xE000 + +; ------------------------------------------------------ +; Monitor Entry points +; ------------------------------------------------------ + +start: JP m_hot_start ; E000 +mon_hexb: JP m_hexb ; E003 +non_con_status: JP m_con_status ; E006 +mon_con_in: JP m_con_in ; E009 +mon_con_out: JP m_con_out ; E00C +mon_serial_in: JP m_serial_in ; E00F +mon_serial_out: JP m_serial_out ; E012 +mon_char_print: JP m_char_print ; E015 +mon_tape_read: JP m_tape_read ; E018 +mon_tape_write: JP m_tape_write ; E01B +ram_disk_read: JP m_ramdisk_read ; E01E +ram_disk_write: JP m_ramdisk_write ; E021 +mon_tape_read_ram: JP m_tape_read_ram2 ; E024 +mon_tape_write_ram: JP m_tape_write_ram2 ; E027 +mon_tape_wait: JP m_tape_wait ; E02A +mon_tape_detect: JP m_tape_blk_detect ; E02D +read_floppy: JP m_read_floppy ; E030 +write_floppy: JP m_write_floppy ; E033 +mon_out_str_z: JP m_out_strz ; E036 + JP m_fn_39 ; E039 + JP get_image_hdr ; E03C + JP esc_picture ; E03F + JP m_print_at_xy ; E042 C-char esc_param[0]=X, [1]=Y + JP esc_draw_fill_rect ; E045 + JP esc_paint ; E048 + JP esc_draw_line ; E04B + JP esc_draw_circle ; E04E + + +; ------------------------------------------------------ +; Init system devices +; ------------------------------------------------------ +m_hot_start: + DI + ;LD SP, M_VARS.rst_ret_jp + LD A, 10000000b ; DD17 all ports to out + OUT (SYS_DD17CTR), A ; VV55 Sys CTR + OUT (DD67CTR), A ; VV55 Video CTR + + ; init_kbd_tape + LD A, 0x93 + OUT (KBD_DD78CTR), A + + + LD A, 01111111b ; VSU=0, C/M=1, FL=111, COL=111 + OUT (VID_DD67PB), A ; color mode + LD A, 00000001b + OUT (SYS_DD17PB), A ; Access to VRAM + LD B, 0x0 ; TODO: replace to LD HL, 0x3f00 LD B,L + LD HL, 0x3f00 + LD A, H + ADD A, 0x41 ; A=128 0x80 + + ; Clear memory from 0x3F00 to 0x7FFF +.fill_video: + LD (HL), B + INC HL + CP H + JP NZ, .fill_video + + ;XOR A + LD A, 0 + OUT (SYS_DD17PB), A ; Disable VRAM + LD A, 00000111b + OUT (SYS_DD17PC), A ; pix shift to 7 + LD (M_VARS.pix_shift), A + + XOR A + LD (M_VARS.screen_mode), A + LD (M_VARS.row_shift), A + + ; Set color mode and palette + LD (M_VARS.curr_color+1), A + CPL + LD (M_VARS.curr_color), A + LD A, 00000011b + LD (M_VARS.cur_palette), A + ; VSU=0, C/M=1, FL=000, COL=011 + ; color mode, black border + ; 00-black, 01-red, 10-purple, 11-white + LD A, 01000011b + OUT (VID_DD67PB), A + + ; config LPT + LD A, 0x4 + OUT (DD67PC), A ; bell=1, strobe=0 + LD (M_VARS.strobe_state), A ; store strobe + LD HL, 1024 ; 683us + LD (M_VARS.beep_period), HL + LD HL, 320 ; 213us + LD (M_VARS.beep_duration), HL + +.conf_uart: + ; Config UART + LD A, 11001110b + OUT (UART_DD72RR), A + LD A, 00100101b + OUT (UART_DD72RR), A + + ; Config Timer#1 for UART clock + LD A, 01110110b ; tmr#1, load l+m bin, sq wave + OUT (TMR_DD70CTR), A + + ; 1.5M/20 = 75kHz + LD A, 20 + OUT (TMR_DD70C2), A + XOR A + OUT (TMR_DD70C2), A +.conf_pic: + ; Config PIC + LD A,00010010b ; ICW1 edge trigger, interval 8, sin... + OUT (PIC_DD75RS), A + XOR A + OUT (PIC_DD75RM), A ; ICW2 + CPL + OUT (PIC_DD75RM), A ; ICW3 no slave + LD A,00100000b + OUT (PIC_DD75RS), A ; Non-specific EOI command, End of I... + LD A, PIC_POLL_MODE + OUT (PIC_DD75RS), A ; Poll mode, poll on next RD + + LD A, 0x80 + OUT (KBD_DD78PC), A ; TODO: - Check using this 7th bit + NOP + NOP + XOR A + OUT (KBD_DD78PC), A + + ; Init cursor + LD SP, M_VARS.stack1 + CALL m_draw_cursor + + ; Beep + LD C, ASCII_BELL + CALL m_con_out + + LD A, (BIOS.boot_f) + CP JP_OPCODE + JP Z, BIOS.boot_f + LD HL, mgs_system_nf + CALL m_out_strz + JP m_sys_halt + +; -------------------------------------------------- +; Output ASCIIZ string +; Inp: HL -> string +; -------------------------------------------------- +m_out_strz: + LD C, (HL) + LD A, C + OR A + RET Z + CALL m_con_out + INC HL + JP m_out_strz + +mgs_system_nf: + DB "\r\nSYSTEM NOT FOUND\r\n", 0 + +m_sys_halt: + HALT + +; ------------------------------------------------------ +; Console status +; Out: A = 0 - not ready +; A = 0xFF - ready (key pressed) +; ------------------------------------------------------ +m_con_status: + IN A, (PIC_DD75RS) ; Read PIC status + NOP + AND KBD_IRQ ; Check keyboard request RST1 + LD A, 0 + RET Z ; no key pressed + CPL + RET ; key pressed + +; ------------------------------------------------------ +; Wait and read data from UART +; Out: A - 7 bit data +; ------------------------------------------------------ +m_serial_in: + IN A, (UART_DD72RR) + AND RX_READY + JP Z, m_serial_in ; wait for rx data ready + IN A, (UART_DD72RD) + AND 0x7f ; leave 7 bits + RET + +; ------------------------------------------------------ +; Read key +; Out: A +; ------------------------------------------------------ +m_con_in: + CALL m_con_status + OR A + JP Z, m_con_in ; wait key + IN A, (KBD_DD78PA) ; get key + ;AND 0x7f ; reset hi bit, leave 0..127 code + NOP ; DIFF: do not reset hi bit + NOP + PUSH AF + ; TODO: Check if it is keyboard ACK + ; PC7 Set Hi (ACK?) + LD A, 0x80 + OUT (KBD_DD78PC), A + ; PC7 Set Lo + XOR A + OUT (KBD_DD78PC), A + POP AF + RET + +; ------------------------------------------------------ +; Send data by UART +; Inp: C - data to transmitt +; ------------------------------------------------------ +m_serial_out: + IN A, (UART_DD72RR) + AND TX_READY + JP Z, m_serial_out ; Wait for TX ready + LD A, C + OUT (UART_DD72RD), A + RET + +; ------------------------------------------------------ +; Send character to printer +; Inp: C - character +; ------------------------------------------------------ +m_char_print: + ; wait printer ready + IN A, (PIC_DD75RS) + AND PRINTER_IRQ + JP Z, m_char_print + + LD A, C + NOP + OUT (LPT_DD67PA), A + ; set LP strobe + LD A, 00010100b + OUT (DD67PC),A + +.wait_lp: + ; wait printer ack + IN A, (PIC_DD75RS) + AND PRINTER_IRQ + JP NZ, .wait_lp + ; remove LP strobe + LD A, 00000100b + OUT (DD67PC), A + RET + +; ------------------------------------------------------ +; Out char to console +; Inp: C - char +; ------------------------------------------------------ +m_con_out: + PUSH HL + PUSH DE + PUSH BC + CALL m_con_out_int + POP BC + POP DE + POP HL + RET + +; ------------------------------------------------------ +; Out char C to console +; ------------------------------------------------------ +m_con_out_int: + LD DE, M_VARS.esc_mode + LD A, (DE) + DEC A + OR A ; TODO: unused (save 1b 4t) + JP M, m_print_no_esc ; esc_mode=0 - standart print no ESC mode + JP NZ, m_print_at_xy ; esc_mode=2 (graphics) + + ; handle ESC param (esc_mode=1) + INC DE ; TODO: replace to INC E E=0xd3 save 2t + LD A, (DE) + OR A + JP P, get_esc_param + LD A, C + AND 0xf ; convert char to command code + LD (DE), A + INC DE ; TODO: replace to INC E E=0xd3 save 2t + XOR A + LD (DE), A + RET + +get_esc_param: + LD HL, M_VARS.esc_cmd + LD B, (HL) ; TODO: replace to INC L L=0xd4 save 2t + INC HL ; HL -> param count + LD A, (HL) + INC A + LD (HL), A + ; store new param + LD E, A + LD D, 0x0 + ADD HL, DE ; HL -> parameter[param_count] + LD (HL), C ; store letter as esc parameter + ; get params count for esc command + LD HL, esc_params_tab + LD E, B ; d=0, b = cmd + ADD HL, DE ; DE - command offset + CP (HL) + ; return if enough + RET M + +;esc_set_mode: + LD HL, M_VARS.esc_cmd + LD A, (HL) + AND 0x0f ; mask (cmd=0..15) + LD E, A + DEC HL ; HL -> esc_mode + OR A + LD (HL), 2 ; mode=2 for cmd=0 + RET Z ; just return, no handler there + + LD D, 0 ; TODO: remove, D already 0 + LD (HL), D ; reset mode to 0 for other + DEC DE ; DE = cmd-1 + +;co_get_hdlr: + ; Calc ESC command handler offset + LD HL, esc_handler_tab + ADD HL, DE + ADD HL, DE + LD E, (HL) + INC HL + LD D, (HL) + ; HL = addr of handler func + EX DE, HL + ; It is 1..4 func DRAW_* func? + CP 0x4 + JP P, esc_no_draw_fn + LD A, (M_VARS.screen_mode) + AND 00000011b + ; If not in graphics mode - exit + JP NZ, esc_exit + +esc_no_draw_fn: + LD DE, esc_exit + PUSH DE + + ; Jump to ESC func handler + JP (HL) + +esc_exit: + XOR A + LD (M_VARS.esc_mode), A + RET + + ; Count of parameters for ESC commands + ; 0xe1cb +esc_params_tab: + DB 3, 5, 4, 3, 1, 2, 1, 1 + DB 1, 2, 1, 5, 5, 7, 6, 4 + +esc_handler_tab: + DW esc_draw_fill_rect ;5 1x1y1x2y2m + DW esc_draw_line ;4 2x1y1x2y2 + DW esc_draw_dot ;3 3xxyy + DW esc_set_color ;1 4N N=1..4 + DW esc_set_cursor ;2 5rc r-Row, c-Col + DW esc_set_vmode ;1 6m m-mode: + ; C 0 - 40x25 cursor on + ; M 1,2 - 64x25 cursor on + ; M 3 - 80x25 cursor on + ; C 4 - 40x25 cursor off + ; M 5,6 - 64x25 cursor off + ; M 7 - 80x25 cursor off + ; M 8 - 20rows mode + ; 9 - cursor off + ; 10 - cursor on + DW esc_set_charset ;1 7n where n is: + ; 0 - LAT Both cases + ; 1 - RUS Both cases + ; 2 - LAT+RUS Upper case + DW esc_set_palette ;1 8c c - Foreground+Backgound + DW esc_set_cursor2 ;2 9xy + DW esc_print_screen ;1 : + DW esc_draw_circle ;5 ;xyraxay X,Y, Radius, aspect ratio X, aspect ratio Y + DW esc_paint ;5 = + DW esc_picture ;6 > + DW esc_set_beep ;4 ?ppdd pp-period (word), dd - duration (word) + +esc_set_beep: + ; param byte 1+2 -> period + LD DE, M_VARS.esc_param + LD A, (DE) + LD H, A + INC DE + LD A, (DE) + LD L, A + LD (M_VARS.beep_period), HL + ; param byte 3+4 -> duration + INC DE + LD A, (DE) + LD H, A + INC DE + LD A, (DE) + LD L, A + LD (M_VARS.beep_duration), HL + RET + +esc_set_cursor2: + JP esc_set_cursor + +esc_print_screen: + LD A, (M_VARS.screen_mode) + AND 00000011b + RET NZ ; ret if not 0-3 mode + LD DE, 0x30ff + CALL m_print_hor_line + DEC E + LD D, 0xf0 + +.chk_keys: + CALL m_con_status + OR A + JP Z, .no_keys + CALL m_con_in + CP ASCII_ESC + RET Z + +.no_keys: + CALL m_print_hor_line + DEC E + JP NZ, .chk_keys + LD D, 0xe0 ; 224d + CALL m_print_hor_line + RET + +; ------------------------------------------------------ +; Print line to printer +; D - width +; ------------------------------------------------------ +m_print_hor_line: + LD HL, cmd_esc_set_X0 + + ; Set printer X coordinate = 0 + CALL m_print_cmd + LD HL, 4 + LD (M_VARS.ul_var0), HL ; Set start coord X = 4 + LD B, 0x0 ; TODO: LD B, H (save 1b 3t) + +.print_next_col: + LD C, 0x0 + ; 1 + CALL m_get_7vpix + AND D + CALL NZ, m_print_vert_7pix + LD HL, (M_VARS.ul_var0) + INC HL + + ; inc X + LD (M_VARS.ul_var0), HL + LD C, 0x1 + ; 2 + CALL m_get_7vpix + AND D + CALL NZ, m_print_vert_7pix + LD HL, (M_VARS.ul_var0) + INC HL + ; inc X + LD (M_VARS.ul_var0), HL + INC B + LD A, B + CP 236 + JP C, .print_next_col + LD HL, cmd_esc_inc_Y2 + CALL m_print_cmd + RET + +; ------------------------------------------------------ +; Send command to printer +; Inp: HL -> command bytes array +; ------------------------------------------------------ +m_print_cmd: + PUSH BC +.print_nxt: + LD A, (HL) + CP ESC_CMD_END + JP Z, .cmd_end + LD C, A + CALL m_char_print + INC HL + JP .print_nxt +.cmd_end: + POP BC + RET + +; ------------------------------------------------------ +; Print 7 vertical pixels to printer +; Inp: A - value to print +; ------------------------------------------------------ +m_print_vert_7pix: + PUSH AF + ; Set coordinate X to 0 + LD HL, cmd_esc_set_X + CALL m_print_cmd + LD HL, (M_VARS.ul_var0) + LD C,H + CALL m_char_print + LD C,L + CALL m_char_print + ; Set column print mode + LD HL, cmd_esc_print_col + CALL m_print_cmd + POP AF + ; Print 7 vertical pixels + LD C, A + CALL m_char_print + RET + +; ------------------------------------------------------ +; Control codes for printer УВВПЧ-30-004 +; ------------------------------------------------------ +; Zn - Increment Y coordinate +; 0xe2a5 +cmd_esc_inc_Y2: + DB ASCII_ESC + DB 'Z' + DB 2h + DB ESC_CMD_END + +; Xnn - Set X coordinate +cmd_esc_set_X0: + DB ASCII_ESC + DB 'X' + DB 0h ; 0..479 + DB 0h + DB ESC_CMD_END + +; ------------------------------------------------------ +; X - Start on "Set X coordinate" command +; ------------------------------------------------------ +cmd_esc_set_X: + DB ASCII_ESC + DB 'X' + DB ESC_CMD_END + +; O - Column print (vertical 7 bit) +cmd_esc_print_col: + DB ASCII_ESC + DB 'O' + DB ESC_CMD_END + +; ------------------------------------------------------ +; Get 7 vertical pixels from screen +; Inp: C - sheet +; Out: A - byte +; ------------------------------------------------------ +m_get_7vpix: + LD A, (M_VARS.row_shift) + ADD A, B + ADD A, 19 ; skip first 20pix + LD L, A + PUSH DE + PUSH BC + LD A, E + +.calc_pix_no: + AND 0x7 + LD B, A + LD A, E + ; calc hi addr + RRA ; /8 + RRA + RRA + AND 0x1f + ADD A, A ; *2 + ADD A, 64 ; bytes per row + LD H, A + ; select sheet 0|1 + LD A, C + AND 0x1 + ADD A, H + LD H, A + ; HL = pix addr, turn on VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + LD E, (HL) ; read pixel + INC H ; HL += 512 + INC H + LD D, (HL) ; read pixel row+1 + + ; turn off VRAM access + ;v8 XOR A + LD A, 0 + OUT (SYS_DD17PB), A +.for_all_pix: + DEC B + JP M, .all_shifted + ; shift pixels D >> [CF] >> E + LD A, D + RRA + LD D, A + LD A, E + RRA + LD E, A + JP .for_all_pix +.all_shifted: + LD A, E + LD D, 0 + RRA + JP NC,.not_1_1 + LD D,00110000b +.not_1_1: + RRA + JP NC, .not_1_2 + LD A, D + OR 11000000b + LD D, A +.not_1_2: + LD A, D + POP BC + POP DE + RET + +esc_set_palette: + LD A, (M_VARS.esc_param) + AND 00111111b ; bgcol[2,1,0],pal[2,1,0] + LD (M_VARS.cur_palette), A + LD B, A + LD A, (M_VARS.screen_mode) + AND 00000011b + LD A, 0x0 + JP NZ, esp_no_colr + LD A, 0x40 + +esp_no_colr: + OR B + OUT (VID_DD67PB), A + RET + +esc_set_charset: + LD A, (M_VARS.esc_param) + AND 0x3 ; charset 0..3 + LD (M_VARS.codepage), A + RET + +; ------------------------------------------------------ +; Get address for draw symbol glyph +; Inp: A - ascii code +; Out: HL -> glyph offset +; ------------------------------------------------------ +m_get_glyph: + LD L, A ; L = ascii code + LD E, A ; E = ascii code + XOR A + LD D, A + LD H, A + ; HL = DE = ascii code + ADD HL, HL + ADD HL, DE + ADD HL, HL + ADD HL, DE + ; HL = A * 7 + LD A, E ; A = A at proc entry + CP '@' + ; First 64 symbols is same for all codepages + JP M, .cp_common + LD A, (M_VARS.codepage) + OR A + ; cp=0 - Latin letters + JP Z, .cp_common + DEC A + ; cp=1 - Russian letters + JP Z, .cp_rus + ; cp=2 - 0x40..0x5F - displayed as Lat + ; 0x60 - 0x7F - displayed as Rus + LD A, E + CP 0x60 + JP M, .cp_common +.cp_rus: + LD DE, 448 ; +448=64*7 Offset for cp1 + ADD HL, DE + +.cp_common: + LD DE, m_font_cp0-224 ; m_font_cp0-32*7 + ADD HL, DE ; add symbol glyph offset + RET + + +; -------------------------------------------------- +; Console output +; Inp: C - char +; -------------------------------------------------- +m_print_no_esc: + LD A, C + AND 0x7f ; C = 0..127 ASCII code + CP ASCII_SP ; C < ' '? + JP M, m_handle_esc_code ; jump if less + CALL m_get_glyph + EX DE, HL + LD A, (M_VARS.screen_mode) + AND 0x3 + JP NZ, mp_mode_64 ; jump to non color modes + + CALL calc_addr_40 + INC L + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + DEC H + DEC H + ; one or two bytes + LD A, B + OR B + JP Z, .l1 + DEC B + JP Z, .l2 + DEC B + JP Z, .l3 + JP .l4 +.l1: + INC H + INC H + LD BC, 0xffc0 + LD A, 0x0 + JP .l5 +.l2: + LD BC, 0xf03f + LD A, 0x6 + JP .l5 +.l3: + LD BC, 0xfc0f + LD A, 0x4 + JP .l5 +.l4: + LD BC, 0xff03 + LD A, 0x2 +.l5: + LD (M_VARS.esc_var1), A + EX DE, HL + +.sym_draw: + LD A, (M_VARS.esc_var1) + PUSH HL + LD L, (HL) + LD H, 0x0 + OR A + JP Z, .pne_l8 + +.pne_l7: + ADD HL, HL + DEC A + JP NZ, .pne_l7 + +.pne_l8: + EX DE, HL + LD A, (HL) + AND C + LD (HL), A + LD A, (M_VARS.curr_color) + AND E + OR (HL) + LD (HL), A + INC H + LD A, (HL) + AND C + LD (HL), A + LD A, (M_VARS.curr_color+1) + AND E + OR (HL) + LD (HL), A + INC H + LD A, (HL) + AND B + LD (HL), A + LD A, (M_VARS.curr_color) + AND D + OR (HL) + LD (HL), A + INC H + LD A, (HL) + AND B + LD (HL), A + LD A, (M_VARS.curr_color+1) + AND D + OR (HL) + LD (HL), A + INC L + DEC H + DEC H + DEC H + EX DE, HL + POP HL + INC HL + LD A, (M_VARS.esc_var0) + DEC A + LD (M_VARS.esc_var0), A + JP NZ, .sym_draw + + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + + ; draw cursor on return + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_rt: + INC HL + LD A, (HL) ; a = col + ADD A, 1 ; col+1 + AND 0x3f ; screen column 0..63 + LD (HL), A ; save new col + CP 40 + DEC HL + RET M ; Return if no wrap + +m40_wrap_rt: + INC HL + XOR A + LD (HL), A + DEC HL + LD A, (M_VARS.screen_mode) + AND 0x08 ; screen_mode=8? + JP NZ, m2_lf + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_lf: + LD A, (HL) + ADD A, 10 + CP 248 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_bksp: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A + AND 0x3f ; A=0..63 + CP 0x3f + JP Z, .wrap + LD (HL), A + DEC HL + RET + +.wrap: + LD A, 39 + LD (HL), A + DEC HL + ; and cursor up + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) +; Inp: HL - cursor pos +; -------------------------------------------------- +m40_up: + LD A, (HL) + SUB 10 ; 10 rows per symbol + JP NC, .up_no_minus + LD A, 240 ; wrap to bottom +.up_no_minus: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor right 8 pos) 20rows mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m20_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x3f ; wrap A=0..63 + LD (HL), A + CP 40 + DEC HL + RET M ; ret if column <40 + JP m40_wrap_rt ; or wrap to next line + +; -------------------------------------------------- +; Calculate VRAM address in 40 column mode +; -------------------------------------------------- +calc_addr_40: + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + CP 4 + LD B, A + JP M, .l2 + AND 0x3 + LD B, A + LD A, H + OR A + RRA + OR A + RRA + LD C, A + LD H, 0x6 + XOR A + +.l1: + ADD A, H + DEC C + JP NZ, .l1 + ADD A, B + +.l2: + ADD A, B + ADD A, 66 + LD H, A + LD A, 0x7 + LD (M_VARS.esc_var0),A + RET + +m2_lf: + LD A, (HL) + ADD A, 10 + CP 15 + JP NC, .lf_nowr + LD (HL), A + RET + +.lf_nowr: + LD A, (M_VARS.row_shift) + LD L, A + ADD A, ASCII_LF + LD E, A + LD C, ASCII_BS + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.cas_l5: + LD B, 0x40 + LD H, 0x40 ; TODO: LD H, B save 1b 3t + LD D, H + +.cas_l6: + LD A, (DE) + LD (HL), A + INC H + INC D + DEC B + JP NZ, .cas_l6 + INC L + INC E + DEC C + JP NZ, .cas_l5 + LD C, 10 + LD A, (M_VARS.row_shift) + ADD A, 8 + LD E, A + +.cas_l7: + LD B, 0x40 + LD D, 0x40 ; TODO: LD D, B save 1b 3t + XOR A + +.cas_l8: + LD (DE),A + INC D + DEC B + JP NZ,.cas_l8 + INC E + DEC C + JP NZ,.cas_l7 + LD A,0x0 + OUT (SYS_DD17PB),A + RET + + +; --------------------------------------------------- +; Handle ASCII_BS (cursor left) in 20row mode +; --------------------------------------------------- +m20_bksp: + INC HL + LD A, (HL) + OR A + DEC HL + RET Z + + INC HL + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x3f + LD (HL), A + DEC HL + RET + +; --------------------------------------------------- +; Print symbol in 64x25 mode +; --------------------------------------------------- +mp_mode_64: + CP 3 ; + JP Z, mp_mode_80 ; jump for screen_mode=3 + ; calc symbol address in VRAM + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + ADD A, 0x40 + LD H, A + ; + LD C, 7 ; symbol height + + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + EX DE, HL + XOR A + LD (DE), A + INC E + +.next_row: + LD A, (HL) + ADD A, A + LD (DE), A + INC HL + INC E + DEC C + JP NZ, .next_row + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + ; draw cursor at end + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_rt: + INC HL + LD A, (HL) + ADD A, 1 + AND 0x3f ; wrap + LD (HL), A + DEC HL + RET NZ ; ret if no wrap + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_lf: + LD A, (HL) + ADD A, 10 + CP 248 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Scroll Up for 10 rows +; -------------------------------------------------- +scroll_up: + LD A, (M_VARS.row_shift) + ADD A, 10 + OUT (SYS_DD17PA), A ; Scroll via VShift register + LD (M_VARS.row_shift), A ; store new VShift value + ; calc bottom 16 rows address in VRAM + LD HL, 0x40f0 ; 240th VRAM byte + ADD A, L + LD L, A + LD C, H + + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + XOR A + LD DE, 0x1040 ; D=16 E=64 (512/8 bytes in row) + +.next_row: + LD H, C + LD B, E + + ; clear 64 bytes (512px in mono or 256px in color mode) +.next_col: + LD (HL), A + INC H ; next column + DEC B + JP NZ, .next_col + INC L ; next row address + DEC D ; row counter - 1 + JP NZ, .next_row + + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_bs: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x3f ; wrap column (0..63) + LD (HL), A + CP 63 + DEC HL + RET NZ + ; cursor up if wrapped + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_up: + LD A, (HL) + SUB 10 + JP NC, .no_wrap + LD A, 240 + +.no_wrap: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor column + 8) in 64x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m64_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x38 + LD (HL), A + DEC HL + RET NZ ; return if no wrap + ; cursor down if wrap + JP m64_lf + +; -------------------------------------------------- +; Print symbols in 80x25 mode +; -------------------------------------------------- +mp_mode_80: + CALL calc_addr_80 + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + ; fix address + EX DE, HL + INC E + ; make bitmask + LD A, B + OR A + JP Z, .l1 + DEC A + JP Z, .l2 + DEC A + JP Z, .l3 + JP .l4 + +.l1: + LD B, (HL) + LD A, (DE) + AND 0xc0 + OR B + LD (DE), A + INC HL + INC E + DEC C + JP NZ, .l1 + JP .l6 +.l2: + LD A, (HL) + RRCA + RRCA + AND 0x7 + LD B, A + LD A, (DE) + AND 0xf0 + OR B + LD (DE), A + LD A, (HL) + RRCA + RRCA + AND 0xc0 + LD B, A + DEC D + LD A, (DE) + AND 0x1f + OR B + LD (DE), A + INC D + INC HL + INC E + DEC C + JP NZ, .l2 + JP .l6 +.l3: + LD A, (HL) + RRCA + RRCA + RRCA + RRCA + AND 0x1 + LD B, A + LD A, (DE) + AND 0xfc + OR B + LD (DE), A + LD A, (HL) + RRCA + RRCA + RRCA + RRCA + AND 0xf0 + LD B, A + DEC D + LD A, (DE) + AND 0x7 + OR B + LD (DE), A + INC D + INC HL + INC E + DEC C + JP NZ, .l3 + JP .l6 +.l4: + DEC D +.l5: + LD A, (HL) + RLCA + RLCA + LD B, A + LD A, (DE) + AND 0x1 + OR B + LD (DE), A + INC HL + INC E + DEC C + JP NZ, .l5 + INC D + +.l6: + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + ; Draw cursor after symbol + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + +; -------------------------------------------------- +; Handle ASCII_CAN (cursor right) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_rt: + INC HL + LD A, (HL) + ADD A, 1 ; inc column + AND 0x7f + LD (HL), A + CP 80 + DEC HL + RET M ; return if no wrap + +m80_col_wrap: + INC HL + XOR A + LD (HL), A + DEC HL + ; and move cursor to next row + +; -------------------------------------------------- +; Handle ASCII_LF (cursor down) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_lf: + LD A, (HL) + ADD A, 10 + CP 248 + JP NC, scroll_up + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_BS (cursor left) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_bs: + INC HL + LD A, (HL) + SUB 1 ; TODO: DEC A - save 1b 2t + AND 0x7f ; mask [0..127] + CP 127 + JP Z, .wrap + LD (HL), A + DEC HL + RET + +.wrap: + LD A, 79 + LD (HL), A + DEC HL + ; and move cursor to previous line + +; -------------------------------------------------- +; Handle ASCII_EM (cursor up) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_up: + LD A, (HL) + SUB 10 + JP NC, .no_wrap + LD A, 240 + +.no_wrap: + LD (HL), A + RET + +; -------------------------------------------------- +; Handle ASCII_TAB (cursor column + 8) in 80x25 mode +; Inp: HL - cursor pos +; -------------------------------------------------- +m80_tab: + INC HL + LD A, (HL) + ADD A, 8 + AND 0x7f + LD (HL), A + CP 80 + DEC HL + RET M ; return if no cursor wrap + JP m80_col_wrap + +; -------------------------------------------------- +; Calculate address for cursor pos for 80x25 mode +; Out: HL -> VRAM +; B -> pixel pos in byte +; -------------------------------------------------- +calc_addr_80: + LD HL, (M_VARS.cursor_row) + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + LD A, H + CP 4 + LD B, A + JP M, mns_ep_fm_0 + AND 3 + LD B, A + LD A, H + OR A + RRA + OR A + RRA + LD C, A + LD H, 3 + XOR A +mns_l1: + ADD A, H + DEC C + JP NZ, mns_l1 + ADD A, B +mns_ep_fm_0: + ADD A, 0x42 + LD H, A + LD C, 0x7 + RET + +; -------------------------------------------------- +; Clear screen and set cursor to 0,0 +; Inp: HL -> cursor position +; -------------------------------------------------- +m_clear_screen: + LD A, (M_VARS.screen_mode) + AND 0x8 + JP NZ, m_clear_20_rows ; for bit 4 is set, clear only 20 rows + ; all in black + LD A, 01111111b + OUT (VID_DD67PB), A ; C/M=1 FL=111 CL=111 All black + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + LD DE, video_ram + EX DE, HL + LD A, H + ADD A, 0x40 ; A=0x80 + LD B, 0 + +.fill_scrn: + LD (HL), B + INC HL + CP H + JP NZ, .fill_scrn ; fill while HL<0x8000 + + EX DE, HL + LD A, (M_VARS.cur_palette) + LD B, A ; B = current palette + LD A, (M_VARS.screen_mode) + AND 0x3 ; color? + LD A, 0x0 + JP NZ, .mono_mode + LD A, 01000000b +.mono_mode: + OR B + ; Restore mode and palette + OUT (VID_DD67PB), A + + ; And set cursor to home position + +; -------------------------------------------------- +; Set cursor to 0,0 and close VRAM access +; Inp: HL -> cursor_row +; -------------------------------------------------- +m_cursor_home: + XOR A + NOP + NOP + LD (HL), A + INC HL + XOR A + LD (HL), A + DEC HL + ;XOR A + LD A, 0 + ; Disable VRAM access + OUT (SYS_DD17PB), A + RET + +; Clear only 20 rows +m_clear_20_rows: + ; take row shift in account + LD A, (M_VARS.row_shift) + LD L, A + LD C, 20 + + ; Access VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.next_row: + LD H, 0x40 ; HL = 0x4000 + shift_row + LD B, 64 ; 64 bytes at row + XOR A +.next_col: + LD (HL), A + INC H ; next column + DEC B + JP NZ, .next_col + INC L ; next row + DEC C + JP NZ, .next_row + ; Disabe VRAM access + LD A, 0 + OUT (SYS_DD17PB), A + JP m_cursor_home + +; -------------------------------------------------- +; Draw cursor at current cursor position +; if not hidden +; -------------------------------------------------- +m_draw_cursor: + LD A, (M_VARS.screen_mode) + AND 0x4 ; check hidden cursor bit + RET NZ ; return if hidden + LD A, (M_VARS.screen_mode) + AND 0x3 ; check color mode (40 column mode 6x7 font) + JP NZ, .dc_mode_64 + + EX DE, HL + LD HL, (M_VARS.cursor_row) + LD A, H ; cursor column + CP 40 ; > 40? + EX DE, HL + RET P ; ret if column out of screen + + PUSH HL + EX DE, HL + CALL calc_addr_40 + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; previous address + DEC H + DEC H + INC L + LD C, 7 ; cursor size + ; build masks + LD A, B + OR B + JP Z, .dc_rt2 + DEC B + JP Z, .dc_mid + DEC B + JP Z, .dc_lt + JP .dc_rt1 +.dc_rt2: + INC H + INC H + LD DE, 0x001f + JP .dc_put +.dc_mid: + LD DE, 0x07c0 + JP .dc_put +.dc_lt: + LD DE, 0x01f0 + JP .dc_put +.dc_rt1: + LD DE, 0x007c + +.dc_put: + ; xor cursor mask with VRAM[HL] value + ; left bytes + LD A, (HL) + XOR E + LD (HL), A + INC H + LD A, (HL) + XOR E + LD (HL), A + ; right bytes + INC H + LD A, (HL) + XOR D + LD (HL), A + INC H + LD A, (HL) + XOR D + LD (HL), A + ; next cursor row address + INC L + DEC H + DEC H + DEC H + DEC C + JP NZ, .dc_put ; draw next cursor row if c>0 + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + POP HL + RET + + ; draw cursor in 64 column mode +.dc_mode_64: + CP 3 ; screen_mode = 3 - 80 rows + JP Z, .dc_mode_80 + EX DE, HL + LD HL, (M_VARS.cursor_row) ; H - col, L - row + ; take into account the vertical shift + LD A, (M_VARS.row_shift) + ADD A, L + LD L, A + ; + LD A, H + CP 64 ; check column + EX DE, HL + RET P ; return if column out of screen + EX DE, HL + ; calc VRAM address + ADD A, 0x40 + LD H, A + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + LD BC, 0x7f08 ; B=01111111b - mask, C=8 - cursor size +.cur_64_next: + ; xor with VRAM content + LD A, (HL) + XOR B + LD (HL), A + ; next row address + INC L + DEC C + JP NZ, .cur_64_next + EX DE, HL + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + + ; draw cursor in 80 column mode +.dc_mode_80 + EX DE, HL + LD HL, (M_VARS.cursor_row) + + LD A, H + CP 80 + EX DE, HL + RET P ; return if column > 80 + + PUSH HL + CALL calc_addr_80 + LD C, 7 ; cursor size + INC L + + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; mask + LD A, B + OR A + LD B, 0x1f + JP Z, .dc_1_byte + DEC A + LD DE, 0xc007 + JP Z, .dc_2_byte + DEC A + LD DE, 0xf001 + JP Z, .dc_2_byte + LD B, 0x7c + DEC H + JP .dc_1_byte ; TODO: unused + +.dc_1_byte: + ; xor with VRAM byte + LD A, (HL) + XOR B + LD (HL), A + INC L + DEC C + JP NZ, .dc_1_byte + JP .dc_80_end + +.dc_2_byte: + ; xor with previous byte + DEC H + LD A, (HL) + XOR D + LD (HL), A + ; xor with current byte + INC H + LD A, (HL) + XOR E + LD (HL), A + ; next cursor address + INC L + DEC C + JP NZ, .dc_2_byte + +.dc_80_end: + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + POP HL + RET + +; -------------------------------------------------- +; If ESC character, turn esc_mode ON +; Inp: A - ASCII symbol +; -------------------------------------------------- +m_handle_esc_code: + CP ASCII_ESC + JP NZ, m_handle_control_code + ; turn on ESC mode for next chars + LD HL, M_VARS.esc_mode + LD (HL), 0x1 ; turn on ESC mode + INC HL + LD (HL), 0xff ; esc_cmd = 0xff + RET + +; -------------------------------------------------- +; Handle one byte ASCII control code +; Inp: A - ASCII symbol +; -------------------------------------------------- +m_handle_control_code: + CP ASCII_BELL + JP Z, m_beep + LD HL, m_draw_cursor + PUSH HL + LD HL, M_VARS.cursor_row + PUSH AF + CALL m_draw_cursor + LD A, (M_VARS.screen_mode) + AND 0x08 ; 20-rows mode? + JP Z, handle_cc_common ; jump for normal screen modes + + ; for hidden cursor modes + POP AF + CP ASCII_TAB ; TAB + JP Z, m20_tab + CP ASCII_BS ; BKSP + JP Z, m20_bksp + CP ASCII_CAN ; Cancel + JP Z, m40_rt + CP ASCII_US ; ASCII Unit separator + JP Z, m_clear_20_rows + CP ASCII_LF ; LF + JP Z, m2_lf + CP ASCII_CR ; CR + RET NZ ; ret on unknown + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; Handle cursor for 40x25, 64x25, 80x25 modes +; -------------------------------------------------- +handle_cc_common: + POP AF + CP ASCII_US + JP Z, m_clear_screen + CP ASCII_FF + JP Z, m_cursor_home + PUSH AF + LD A, (M_VARS.screen_mode) + AND 3 ; check for color modes + JP NZ, .handle_cc_mono + ; 32x25 text mode + POP AF + CP ASCII_TAB ; cursor right +8 + JP Z, m20_tab + CP ASCII_BS ; cursor left + JP Z, m40_bksp + CP ASCII_CAN ; cursor right + JP Z, m40_rt + CP ASCII_EM ; cursor up + JP Z, m40_up + CP ASCII_SUB + JP Z, m40_lf ; cursor down + CP ASCII_LF + JP Z, m40_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 ; move cursor to first column for CR + DEC HL + RET + +; -------------------------------------------------- +; Handle control chars for 64x25 or 80x25 modes +; -------------------------------------------------- +.handle_cc_mono: + LD A, (M_VARS.screen_mode) + CP 3 + JP Z, handle_cc_80x25 + CP 7 + JP Z, handle_cc_80x25 + ; 64x25 screen mode + POP AF + CP ASCII_TAB + JP Z, m64_tab + CP ASCII_BS + JP Z, m64_bs + CP ASCII_CAN + JP Z, m64_rt + CP ASCII_EM + JP Z, m64_up + CP ASCII_SUB + JP Z, m64_lf + CP ASCII_LF + JP Z, m64_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; Handle control chars for 80x25 modes +; -------------------------------------------------- +handle_cc_80x25: + POP AF + CP ASCII_TAB + JP Z, m80_tab + CP ASCII_BS + JP Z, m80_bs + CP ASCII_CAN + JP Z, m80_rt + CP ASCII_EM + JP Z, m80_up + CP ASCII_SUB + JP Z, m80_lf + CP ASCII_LF + JP Z, m80_lf + CP ASCII_CR + RET NZ + INC HL + LD (HL), 0x0 + DEC HL + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +m_beep: + LD HL, (M_VARS.beep_duration) + EX DE, HL + LD HL, (M_VARS.beep_period) + LD A, 00110110b ; TMR#0 LSB+MSB Square Wave Generator + OUT (TMR_DD70CTR), A + LD A, L ; LSB + OUT (TMR_DD70C1), A + LD A, H ; MSB + OUT (TMR_DD70C1), A + LD A, (M_VARS.strobe_state) + LD B, A +m_bell_cont: + LD A, D ; DE=duration + OR E + RET Z ; ret if enough + DEC DE + LD A, B + XOR BELL_PIN + LD B, A + OUT (DD67PC), A ; Invert bell pin +m_bell_wait_tmr1: + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; 0x10 + JP NZ, m_bell_wait_tmr1 + LD A, B + XOR BELL_PIN ; Flip pin again + LD B, A + OUT (DD67PC), A +m_bell_wait_tmr2: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP Z,m_bell_wait_tmr2 + JP m_bell_cont + + +; ------------------------------------------------------ +; 5 Set cursor position +; ------------------------------------------------------ +esc_set_cursor: + CALL m_draw_cursor + LD DE, M_VARS.esc_param + LD HL, M_VARS.cursor_col + INC DE + LD A, (DE) ; column + SUB 32 + LD B, A + LD A, (M_VARS.screen_mode) + CP 3 + JP Z, .mode_80 + CP 7 + JP Z, .mode_80 + OR A + JP Z, .mode_40 + CP 4 + JP Z, .mode_40 + ; mode 64x25 + LD A, B + CP 64 + JP M, .common + LD A, 64 + JP .common + ; mode 40x25 +.mode_40: + LD A, B + CP 40 + JP M, .common + LD A, 40 + JP .common + ; mode 80x25 +.mode_80: + LD A, B + CP 80 + JP M, .common + LD A, 80 +.common: + LD (HL), A + DEC DE + DEC HL + LD A, (DE) + SUB 32 + CP 24 + JP C, esc_le_24 + LD A, 24 +esc_le_24: + LD B, A + ADD A, A + ADD A, A + ADD A, B + ADD A, A + LD (HL), A + CALL m_draw_cursor ; TODO change call+ret to jp + RET ; + +; ------------------------------------------------------ +; 6n Set video mode or cursor visibility +; Inp: n is +; 0 - C 32x25 with cursor; 0000 +; 1 - M 64x25 with cursor; 0001 +; 2 - M 64x25 with cursor; 0010 +; 3 - M 80x25 with cursor; 0011 +; 4 - C 32x25 no cursor; 0100 +; 5 - M 64x25 no cursor; 0101 +; 6 - M 64x25 no cursor; 0110 +; 7 - M 80x25 no cursor; 0111 +; 8 - M 20rows mode 1000 +; 9 - hide cursor 1001 +; 10 - show cursor 1010 +; ------------------------------------------------------ +esc_set_vmode: + LD HL, M_VARS.screen_mode + LD A, (M_VARS.cur_palette) + LD B, A + LD A, (M_VARS.esc_param) ; first parameter - video mode + AND 0xf + CP 11 + RET NC ; return if not valid input parameter + CP 9 + JP Z, .cursor_hide + CP 10 + JP Z, .cursor_show + LD (HL), A ; store new mode + CP 4 + JP Z, .set_color_mode + AND 0x3 ; monochrome (80x25, 64x25) mode? + LD A, 0 ; mode 512x254 mono + JP NZ, .skip_for_mono_mode + ; mode=0 or 4 -> 256x256px color +.set_color_mode: + LD A, 0x40 ; color mode +.skip_for_mono_mode: + OR B ; color mode with palette + OUT (VID_DD67PB), A ; configure screen mode + + LD HL, M_VARS.cursor_row + CALL m_clear_screen + +.draw_cursor: + CALL m_draw_cursor ; TODO change call+ret to jp + RET + +.cursor_hide: + LD A, (HL) ; screen_mode + OR 00000100b ; cursor hide + LD (HL), A + LD HL, M_VARS.cursor_row + JP .draw_cursor + +.cursor_show: + LD A, (HL) ; screen_mode + AND 11111011b ; cursor show + LD (HL), A + JP .draw_cursor + + +; ------------------------------------------------------ +; 4n n=1..4 Set drawing color +; ------------------------------------------------------ +esc_set_color: + LD A, (M_VARS.esc_param) +m_set_color: + AND 0x3 + RRA + LD B, A + LD A, 0x0 ; TODO: unused + SBC A, A + LD (M_VARS.curr_color), A + LD A, B + DEC A + CPL + LD (M_VARS.curr_color+1), A + RET + +;--------------------------------------------------- +; Print symbol or print sprite at X,Y coordinates +; Inp: param x,y +; C - character or sprite_no to draw +;--------------------------------------------------- +m_print_at_xy: + ; check video mode + LD A, (M_VARS.screen_mode) + AND 0x3 ; color? + JP NZ, esc_exit ; exit for mono modes + + LD A, C + AND 0x7f + LD C, A ; C = C with 7th bit reset + CP 0x1 + JP Z, .sprites_en ; enable sprite mode + + CP ASCII_SP + JP M, mode2_exit ; codes 0..31 - turm off game_mode + + ; check X, Y range to prevent drawing symbols out of screen + LD HL, M_VARS.esc_param + LD A, (HL) + LD E, A + ADD A, 8 + JP C, mode2_exit ; exit if esc_param[0]>247 + LD (HL), A + INC HL ; HL -> esc_param[1] + LD A, 247 + CP (HL) + JP C, mode2_exit ; exit if esc_param[1]>247 + ; calculate X,Y pixel address in VRAN + LD D, (HL) + CALL calc_px_addr + ; HL - address, B - pixel pos in byte + LD A, L + SUB 8 + LD L, A + PUSH HL ; save address + + LD A, (M_VARS.esc_var2) + OR A + JP NZ, .mode_sp + + ; font + LD A, C + CALL m_get_glyph + LD C, 7 + POP DE + INC E + JP .out_sp + + ; sprite mode +.mode_sp: + LD A, C + SUB 32 + CP 35 + JP NC, co_ex_l08 + + ; Calc sprite address + LD L, A ; HL=A - sprite_no + XOR A + LD H, A + ADD HL, HL + ADD HL, HL + ADD HL, HL ; HL=HL*8 + LD DE, game_sprite_tab + ADD HL, DE ; HL -> sprite + LD C, 8 ; bytes count + POP DE + + ; Out sprite + ; DE -> VRAM address + ; C - height +.out_sp: + LD A, (M_VARS.esc_param+2) + DEC A + JP Z, out_no_xor + +.next_line: + PUSH HL + ; Access Video RAM + LD A, 0x1 + OUT (SYS_DD17PB), A + LD L, (HL) ; load from table + LD H, 0x0 + LD A, B + OR A + JP Z, .l05 +.l04: + ADD HL, HL + DEC A + JP NZ, .l04 +.l05: + EX DE, HL + LD A, (M_VARS.curr_color) + AND E + XOR (HL) + LD (HL), A + INC H + INC H + LD A, (M_VARS.curr_color) + AND D + XOR (HL) + LD (HL), A + DEC H + LD A, (M_VARS.curr_color+1) + AND E + XOR (HL) + LD (HL), A + INC H + INC H + LD A, (M_VARS.curr_color+1) + AND D + XOR (HL) + LD (HL), A + DEC H + DEC H + DEC H + INC L + EX DE, HL + ; Disable VRAM + LD A, 0x0 + OUT (SYS_DD17PB), A + POP HL + INC HL + DEC C + JP NZ, .next_line + RET + +.sprites_en: + LD (M_VARS.esc_var2), A + RET + +mode2_exit: + XOR A + LD (M_VARS.esc_var2), A + JP esc_exit + +co_ex_l08: + POP DE + JP mode2_exit + +out_no_xor: + PUSH HL + ; Acess to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + LD L, (HL) + LD H, 0x0 + LD A, B + OR A + JP Z, .l11 +.l10: + ADD HL, HL + DEC A + JP NZ, .l10 +.l11: + EX DE, HL + PUSH BC + LD A, (M_VARS.curr_color) + CPL + LD B, A + LD A, (HL) + XOR B + OR E + XOR B + LD (HL), A + INC H + INC H + LD A, (HL) + XOR B + OR D + XOR B + LD (HL), A + DEC H + LD A, (M_VARS.curr_color+1) + CPL + LD B, A + LD A, (HL) + XOR B + OR E + XOR B + LD (HL), A + INC H + INC H + LD A, (HL) + XOR B + OR D + XOR B + LD (HL), A + DEC H + DEC H + DEC H + INC L + EX DE, HL + POP BC + + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + + POP HL + INC HL + DEC C + JP NZ, out_no_xor + RET + +game_sprite_tab: + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; 0x00 + DB 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E ; 0x01 + DB 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E ; 0x02 + DB 0x00, 0x08, 0x08, 0x14, 0x63, 0x14, 0x08, 0x08 ; 0x03 + DB 0x36, 0x7F, 0x7F, 0x7F, 0x3E, 0x1C, 0x08, 0x00 ; 0x04 + DB 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00 ; 0x05 + DB 0x1C, 0x3E, 0x1C, 0x7F, 0x7F, 0x6B, 0x08, 0x1C ; 0x06 + DB 0x08, 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x08, 0x1C ; 0x07 + DB 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18 ; 0x08 + DB 0x18, 0xDB, 0x3C, 0xE7, 0xE7, 0x3C, 0xDB, 0x18 ; 0x09 + DB 0xE7, 0xE7, 0x00, 0x7E, 0x7E, 0x00, 0xE7, 0xE7 ; 0x0a + DB 0x7E, 0x81, 0x81, 0xFF, 0xFF, 0x81, 0x81, 0x7E ; 0x0b + DB 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18 ; 0x0c + DB 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00 ; 0x0d + DB 0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00 ; 0x0e + DB 0x00, 0x08, 0x0C, 0xFE, 0xFE, 0x0C, 0x08, 0x00 ; 0x0f + DB 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 ; 0x10 + DB 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 ; 0x11 + DB 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0 ; 0x12 + DB 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F ; 0x13 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; 0x14 + DB 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ; 0x15 + DB 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F ; 0x16 + DB 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 ; 0x17 + DB 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ; 0x18 + DB 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 ; 0x19 + DB 0x70, 0x08, 0x76, 0xFF, 0xFF, 0xFF, 0x7E, 0x18 ; 0x1a + DB 0xC3, 0xDB, 0xDB, 0x18, 0x18, 0xDB, 0xDB, 0xC3 ; 0x1b + DB 0xFC, 0xCC, 0xFC, 0x0C, 0x0C, 0x0E, 0x0F, 0x07 ; 0x1c + DB 0xFE, 0xC6, 0xFE, 0xC6, 0xC6, 0xE6, 0x67, 0x03 ; 0x1d + DB 0x18, 0x3C, 0x3C, 0x18, 0x7E, 0x18, 0x24, 0x66 ; 0x1e + DB 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 ; 0x1f + DB 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 ; 0x20 + DB 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 ; 0x21 + DB 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF ; 0x22 + +; -------------------------------------------------- +; Calculate address of pixel in Video RAM +; Inp: DE - Y, X +; Out: HL - address +; B - offset in byte +; -------------------------------------------------- +calc_px_addr: + ; take into account the vertical displacement + LD A, (M_VARS.row_shift) + SUB D + DEC A + LD L, A + + LD A, E + AND 0x07 ; X mod 8 - offset in byte + LD B, A + + LD A, E + RRA + RRA + AND 00111110b + ADD A, 0x40 ; VRAM at 0x4000 + LD H, A + RET + + +;--------------------------------------------------- +; Draw filled rectanger +; Inp: esc param X1,Y2,X2,Y2 +; -------------------------------------------------- +esc_draw_fill_rect: + LD HL, M_VARS.esc_param + LD E, (HL) ; E=X1 + INC HL + LD C, (HL) ; C=Y1 + INC HL + INC HL + LD D, (HL) ; D=Y2 + LD A, D + SUB C ; delta Y + JP NZ, .non_zero_h + INC A ; 1 as minimum +.non_zero_h: + LD C, A ; C = height + ; DE = Y2, X1 + CALL calc_px_addr + ; HL -> videomem offset, b - pixel offset + + ; build pixel mask + XOR A +.shift_mask_l: + SCF + RLA + DEC B + JP P, .shift_mask_l + RRA + LD (M_VARS.pixel_mask_l), A + CPL ; invert + LD (M_VARS.pixel_mask_l_i), A + LD A, (M_VARS.esc_param+2) ; X2 + AND 0x7 ; 0..7 + LD B, A + XOR A +.shift_mask_r: + SCF + RLA + DEC B + JP P, .shift_mask_r + LD (M_VARS.pixel_mask_r_i), A + LD B, C + ; calc end address + LD A, (M_VARS.esc_param+2) ; X2 + RRA + RRA + AND 00111110b + ADD A, 0x40 + SUB H + RRCA + LD C, A ; C - width + INC B + LD A, (M_VARS.esc_param+4) + DEC A + JP NZ, .rectangle_xor + LD A, (M_VARS.pixel_mask_r_i) + CPL + LD (M_VARS.pixel_mask_r), A + LD D, A + LD A, (M_VARS.pixel_mask_l) + LD E, A + ; draw B horisontal lines +.next_line: + PUSH DE + PUSH HL + PUSH BC + CALL draw_line_h + POP BC + POP HL + POP DE + INC L + DEC B + JP NZ, .next_line + RET + + ; draw B horisontal lines (xor) +.rectangle_xor: + LD A, (M_VARS.pixel_mask_r_i) + LD (M_VARS.pixel_mask_r), A + LD D, A + LD A, (M_VARS.pixel_mask_l_i) + LD E, A + ; Access to VideoRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + +.edf_l6: + PUSH DE + PUSH HL + PUSH BC + LD A, C + OR A + JP NZ, .w_ne_0 ; jump if width != 0 + LD A, E ; merge masks E=E or D + OR D +.next_8px: + LD E, A +.w_ne_0: + LD B, E ; B - mask + EX DE, HL + LD HL, (M_VARS.curr_color) ; color + EX DE, HL + ; Set pixels - VideoRAM[HL] = color xor VideoRAM[HL] + LD A, E + AND B + XOR (HL) + LD (HL), A + ; And next byte + INC H + LD A, D + AND B + XOR (HL) + LD (HL), A + ; ---------- + INC H + LD A, C + OR A + JP Z, .complete + DEC C + ; right tail of line, use right mask +.r_mask: + LD A, (M_VARS.pixel_mask_r) + JP Z, .next_8px + ; full 8 bits without mask at middle of line +.next_full: + LD A, (HL) + XOR E + LD (HL), A + INC H + LD A, (HL) + XOR D + LD (HL), A + INC H + DEC C + JP NZ, .next_full + JP .r_mask +.complete: + POP BC + POP HL + POP DE + INC L + DEC B + JP NZ, .edf_l6 + ; Disable VideoRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +;--------------------------------------------------- +; Paint screen +; Inp: params X,Y,Color,repColor +;--------------------------------------------------- +esc_paint: + ; Save stack + LD HL, 0x0 + ADD HL, SP + LD (M_VARS.paint_sp_save), HL + + ; Set our own stack + LD HL, M_VARS.paint_stack ; TODO: Z80 LD SP,var i800 - LXI SP,nn + LD SP, HL + + ; save current color + LD HL, (M_VARS.curr_color) + LD (M_VARS.tmp_color), HL + + ; set color from param 3 + LD A, (M_VARS.esc_param+2) + DEC A + CALL m_set_color + + ; color to replace, from param 4 + LD A, (M_VARS.esc_param+3) + DEC A + LD (M_VARS.cmp_color), A + + ; HL - Y,X + LD A, (M_VARS.esc_param) + LD L, A + LD A, (M_VARS.esc_param+1) + LD H, A + LD (M_VARS.paint_y), A + + LD A, (M_VARS.esc_param+4) ; 0 - full fill, 1 - fast fill + DEC A + LD (M_VARS.esc_param), A + + LD A, 0x2 + LD (M_VARS.paint_var5), A ; task_no=2 + + EX DE, HL + CALL calc_px_addr + LD (M_VARS.esc_param+1), HL ; temporary ctore address of start fill point + ; make mask + LD A, 10000000b +.l1: + RLCA + DEC B + JP P, .l1 + + LD B, A + LD (M_VARS.esc_param+3), A ; store mask + + ; find left border + LD A, (M_VARS.cmp_color) + LD C, A + LD D, E ; D = X + CALL paint_find_left + ; find right border + LD HL, (M_VARS.esc_param+1) ; restore HL + LD A, (M_VARS.esc_param+3) ; restore mask + LD B, A + CALL paint_find_right + ; + LD HL, 0x0 + PUSH HL + PUSH HL + ; + LD A, (M_VARS.esc_param) ; A = fill mode + OR A + JP Z, ep_fm_0 + ; push fill task parameters + LD A, (M_VARS.paint_var5) + DEC A ; task_no-1 + LD H, A + LD L, E + PUSH HL + LD A, (M_VARS.paint_y) + LD H, A + LD L, D + PUSH HL + +ep_fm_0: + ; push fill task parameters + LD A, (M_VARS.paint_var5) ; task_no + LD H, A + LD L, E + PUSH HL + LD A, (M_VARS.paint_y) + LD H, A + LD L, D + PUSH HL + JP paint_task ; exec task + +ep_task_end: + LD A, (M_VARS.cmp_color) + LD C, A ; color to compare + + LD A, (M_VARS.esc_param) ; fill mode 0 - full, 1 - fast + OR A + JP NZ, ep_f_fast + + LD A, 0x2 + LD (M_VARS.paint_var7), A + LD A, (M_VARS.paint_var2) + CP 2 + JP Z, ep_l4 + JP ep_l5 ; TODO: change to one JP NZ + +ep_l4: + LD A, 1 + LD (M_VARS.paint_var5), A ; task_no? + JP ep_l8 + +ep_l5: + LD A, 2 + LD (M_VARS.paint_var5), A + JP ep_l11 + +ep_l6: + LD A, (M_VARS.paint_var7) + OR A + JP Z, paint_task + LD A, (M_VARS.paint_var2) + CP 2 + JP Z, ep_l5 ; TODO: change to one JP NZ + JP ep_l4 + +ep_f_fast: + LD A, (M_VARS.paint_var2) + LD (M_VARS.paint_var5), A + CP 1 ; TODO: DEC A - save 1b 3t + JP Z, ep_l8 ; TODO: change to one JP NZ + JP ep_l11 + +ep_l8: + LD A, (M_VARS.paint_var3) + LD D, A + LD A, (M_VARS.paint_var1) + LD E, A + LD HL, (M_VARS.esc_param+1) + LD A, (M_VARS.esc_param+3) + LD B, A + LD A, (M_VARS.paint_var4) + DEC A + JP Z, ep_l10 + LD (M_VARS.paint_y), A + INC L + CALL paint_find_next_right + JP Z, ep_l10 + LD HL, (M_VARS.esc_param+4) + LD A, (M_VARS.esc_param+6) + LD B, A + INC L + CALL paint_find_next_left + JP Z, ep_l10 + LD A, (M_VARS.esc_param) + OR A + JP NZ, ep_l9 + JP ep_l12 + +ep_l9: + LD A, (M_VARS.paint_var5) + LD H, A + LD L, E + PUSH HL + LD A, (M_VARS.paint_y) + LD H, A + LD L, D + PUSH HL + JP paint_task + +ep_l10: + LD A, (M_VARS.esc_param) + OR A + JP NZ, paint_task + LD A, (M_VARS.paint_var7) + DEC A + LD (M_VARS.paint_var7), A + JP ep_l6 + +ep_l11: + LD A, (M_VARS.paint_var3) + LD D, A + LD A, (M_VARS.paint_var1) + LD E, A + LD HL, (M_VARS.esc_param+1) + LD A, (M_VARS.esc_param+3) + LD B, A + LD A, (M_VARS.paint_var4) + INC A + CP 0xff + JP Z, ep_l10 + LD (M_VARS.paint_y), A + DEC L + CALL paint_find_next_right + JP Z, ep_l10 + LD HL, (M_VARS.esc_param+4) + LD A, (M_VARS.esc_param+6) + LD B, A + DEC L + CALL paint_find_next_left + JP Z, ep_l10 + LD A, (M_VARS.esc_param) + OR A + JP NZ, ep_l9 + JP ep_l12 + +; --------------------------------------------------- +; +; --------------------------------------------------- +paint_find_next_right: + CALL get_pixel + JP NZ, .l1 + CALL paint_find_left + LD A, 0xff + OR A + RET + +.l1: + LD A, D + CP E + RET Z + INC D + LD A, B + RLCA + LD B, A + JP NC, .l2 + INC H + INC H +.l2: + CALL get_pixel + JP NZ, .l1 + LD A, 0xff + OR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +paint_find_next_left: + CALL get_pixel + JP NZ, .l1 + CALL paint_find_right + LD A, 0xff + OR A + RET +.l1: + LD A, E + CP D + RET Z + DEC E + LD A, B + RRCA + LD B, A + JP NC, .l2 + DEC H + DEC H +.l2: + CALL get_pixel + JP NZ, .l1 + LD A, 0xff + OR A + RET + +ep_l12: + LD A, D + LD (M_VARS.pixel_mask_r), A + LD A, (M_VARS.paint_var5) + LD D, A + PUSH DE + LD A, (M_VARS.pixel_mask_r) + CP E + JP NZ, ep_l13 + LD L, A + LD A, (M_VARS.paint_y) + LD H, A + PUSH HL + JP ep_l16 +ep_l13: + LD D, E + CALL paint_find_left + LD E, D + LD A, (M_VARS.paint_y) + LD D, A + PUSH DE + LD A, (M_VARS.pixel_mask_r) + LD D, A + CP E + JP Z, ep_l16 +ep_l14: + DEC E + LD A, B + RRCA + LD B, A + JP NC, ep_l15 + DEC H + DEC H +ep_l15: + CALL get_pixel + JP NZ, ep_l14 + JP ep_l12 +ep_l16: + JP ep_l10 + +; --------------------------------------------------- +; Find rightmost pixel to fill +; In/Out: E = x_right +; HL - current pixel address +; B - pixel mask +; --------------------------------------------------- +paint_find_right: + LD A, E + CP 0xff + RET Z ; return if X=right border + INC E ; x=x+1 + ; rotate pixel mask right + LD A, B + RLCA + LD B, A + JP NC, .in_byte + ; inc addr+2 (2 byte per 8 pixels) + INC H + INC H + +.in_byte: + CALL get_pixel + JP Z, paint_find_right ; find until same color + ; border found, x-1 + DEC E + ; rotate mask back 1 px + LD A, B + RRCA + LD B, A + RET NC + ; addr-2 if previous byte + DEC H + DEC H + RET + +; --------------------------------------------------- +; Find leftmost pixel to fill +; In/Out: D = x_left +; HL - current pixel address +; B - pixel mask +; --------------------------------------------------- +paint_find_left: + LD A, D + OR A + RET Z ; return if x=0 + + DEC D ; x-1 + LD A, B + RRCA ; rotate mask to right + LD B, A + JP NC, .in_byte + DEC H ; addr-2 (2 byte for 8px) + DEC H + +.in_byte: + CALL get_pixel + JP Z, paint_find_left ; repeat until same color + + INC D ; border found, x+1 + ; mask rotate right + LD A, B + RLCA + LD B, A + RET NC + ; if CF, inc address+2 + INC H + INC H + RET + +; --------------------------------------------------- +; Inp: HL - address +; B - pixel mask +; C - color to compare +; Out: A - 0,1,2 +; ZF - set if color match +; --------------------------------------------------- +get_pixel: + ; Access to VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; get pixel and mask + LD A, (HL) + AND B + JP NZ, .bit1_set + INC H + LD A, (HL) + DEC H + AND B + JP NZ, .bit2_set + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + CP C + RET + +.bit1_set: + INC H + LD A, (HL) + DEC H + AND B + JP NZ, .bit12_set + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + LD A, 0x1 + CP C + RET + +.bit2_set: + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + LD A, 0x2 + CP C + RET + +.bit12_set: + LD A, 0x0 + OUT (SYS_DD17PB), A + LD A, 3 + CP C + RET + +paint_task: + POP HL ; L=x0, H=Y + LD (M_VARS.paint_var3), HL + EX DE, HL + + POP HL ; L=x1, H=mode + LD A, H + OR A + JP Z, paint_exit ; jump for mode=0 + + ; calc leftmost pixel address, mask for draw horisontal line + LD (M_VARS.paint_var1), HL + CALL calc_px_addr + LD (M_VARS.esc_param+1), HL + LD C, B + LD A, 0x80 +.lmp_mask: + RLCA + DEC B + JP P, .lmp_mask + LD (M_VARS.esc_param+3), A + ; calc rightmos pixel address and mask + LD A, (M_VARS.paint_var1) + LD E, A + LD A, (M_VARS.paint_var4) + LD D, A + CALL calc_px_addr + LD (M_VARS.esc_param+4), HL + LD D, B + LD A, 0x80 +.rmp_mask: + RLCA + DEC B + JP P, .rmp_mask + LD (M_VARS.esc_param+6), A + LD A, (M_VARS.esc_param+3) ; TODO: unused code + + XOR A +.lmi_mask: + SCF + RLA + DEC C + JP P, .lmi_mask + RRA + LD E, A ; E - left inv mask + + XOR A +.rmi_mask: + SCF + RLA + DEC D + JP P, .rmi_mask + CPL + LD D, A ; D - right inv mask + + LD (M_VARS.pixel_mask_r), A + LD HL, (M_VARS.esc_param+1) ; HL -> lext pix address + LD A, (M_VARS.esc_param+5) ; right pix address (low byte) + SUB H ; delta x + RRCA ; 2 byte for 8 pix + LD C, A ; C - line width + CALL draw_line_h + JP ep_task_end + +paint_exit: + LD HL, (M_VARS.tmp_color) ; restore previous current color + LD (M_VARS.curr_color), HL + LD HL, (M_VARS.paint_sp_save) ; restore previous stack + LD SP, HL + RET + +;--------------------------------------------------- +; Draw horizontal line +; Inp: C - width +; DE - left & right pixel mask +; HL - address of first byte of line +;--------------------------------------------------- +draw_line_h: + ; Access to VideoRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, C + OR A + JP NZ, .width_ne0 + LD A, E ; join left and right masks + OR D +.next_byte: + LD E, A +.width_ne0: + LD B, E + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Get pixels, apply colors + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A ; store first + ; Same for second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; move to next byte + INC H + LD A, C + OR A + JP Z, .complete + DEC C +.r_mask: + ; use right mask for last right byte + LD A, (M_VARS.pixel_mask_r) + JP Z, .next_byte +.full_8: + LD (HL), E + INC H + LD (HL), D + INC H + DEC C + JP NZ, .full_8 + JP .r_mask +.complete: ; TODO: duplicate close_vram_ret + ; Disable VideoRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +;--------------------------------------------------- +; 2x1y1x2y2 Draw Line +;--------------------------------------------------- +esc_draw_line: + LD HL, M_VARS.esc_param + LD E, (HL) ; E=X1 + INC HL + LD D, (HL) ; D=Y1 + INC HL + LD A, (HL) + INC HL + LD H, (HL) ; H=Y2 + LD L, A ; L=X2 + CP E + JP C, .x1_le_x2 + EX DE, HL ; exchange if X1>X2 +.x1_le_x2: + LD (M_VARS.esc_param), HL ; store x1,y1 back + LD A, E + SUB L + LD L, A ; L - width + LD A, D + SUB H + LD H, A ; H - height + PUSH AF + JP NC, .pos_height + ; change sign + CPL + INC A + LD H, A +.pos_height: + EX DE, HL + LD HL, (M_VARS.esc_param) + EX DE, HL + JP Z, height0 + LD A, L + OR A + JP Z, .width0 + LD B, A + POP AF + LD A, 0x0 + ADC A, A + LD (M_VARS.esc_param+4), A + ; HL = E/B height/width + LD E, H + LD C, 16 + LD D, 0 +.next_16: + ADD HL, HL + EX DE, HL + ADD HL, HL + EX DE, HL + LD A, D + JP C, .edl_l4 + CP B + JP C, .edl_l5 +.edl_l4: + SUB B + LD D, A + INC HL +.edl_l5: + DEC C + JP NZ, .next_16 + LD DE, 0x0 + PUSH DE + ; save result at stack + PUSH HL + + LD HL, (M_VARS.esc_param) ; x1,y1 + EX DE, HL + LD C, B + CALL calc_px_addr + ; HL - address, B - offset in byte + ; make mask + LD A, 10000000b +.roll_l: + RLCA + DEC B + JP P, .roll_l + CPL + LD B, A ; b - inv mask + +.edl_l7 + POP DE + EX (SP), HL ; save HL on top of stack + LD A, H + ADD HL, DE + SUB H + CPL + INC A + EX (SP), HL + PUSH DE + PUSH BC + LD C, A + EX DE, HL + + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Access VideoRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + + LD A, (M_VARS.esc_param+4) ; sign of delta Y + OR A + JP NZ, .next_down +.next_up: + ; firs byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + DEC H + LD A, C + OR A + JP Z, .is_last + DEC C + ; draw up + DEC L + JP .next_up +.next_down: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; + DEC H + LD A, C + OR A + JP Z, .is_last + DEC C + ; draw down + INC L + JP .next_down +.is_last: + ; Disable VideoRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + POP BC + LD A, B + ; <<1px + SCF + RLA + JP C, .edl_l11 + RLA + INC H + INC H +.edl_l11 + LD B, A + DEC C + JP NZ, .edl_l7 + POP HL + POP HL + RET + +; -------------------------------------------------- +; draw vertical line +; Inp: DE - YX +; L - length +; -------------------------------------------------- +.width0 + LD C, H + CALL calc_px_addr + + ; make pixel mask + LD A, 10000000b +.edl_l13: + RLCA + DEC B + JP P, .edl_l13 + CPL + LD B, A + + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + POP AF + + ; Enable VRAM + LD A, 0x1 + OUT (SYS_DD17PB), A + JP C, .next_row_down + +.next_row_up: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next Y + DEC H + LD A, C + OR A + JP Z, close_vram_ret + DEC C + ; dec row + DEC L + JP .next_row_up + +.next_row_down: + ; first byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; second byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next address + DEC H + LD A, C + OR A + JP Z, close_vram_ret + DEC C + ; inc row + INC L + JP .next_row_down + +close_vram_ret + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; draw horizontal line +; Inp: DE - YX +; L - length +; -------------------------------------------------- +height0 + POP AF + LD C, L + LD A, L + OR A + JP NZ, .len_ne0 + INC C ; length 1 at least +.len_ne0: + CALL calc_px_addr + ; make pixel mask + LD A, 10000000b +.edl_l19 + RLCA + DEC B + JP P, .edl_l19 + CPL + LD B, A + + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + + ; Enable VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + +.next_col: + ; set 1st byte + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; set 2nd byte + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; next byte + DEC H + ; next (right) horizontal pixel + LD A, B + SCF + RLA + JP C, .edl_l21 + RLA + INC H + INC H +.edl_l21 + LD B, A + DEC C + JP NZ, .next_col + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; -------------------------------------------------- +; ESC Draw Dot +; -------------------------------------------------- +esc_draw_dot: + LD HL, (M_VARS.esc_param) + EX DE, HL + CALL calc_px_addr + LD A, 0x80 +edd_l1 + RLCA + DEC B + JP P, edd_l1 + LD B, A + LD A, (M_VARS.esc_param+2) + CP 0x3 + JP Z, edd_ep_task_end + LD A, B + CPL + LD B, A + LD A, (M_VARS.esc_param+2) + CP 0x2 + JP Z, edd_ep_fm_0 + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, (HL) + AND B + LD (HL), A + INC H + LD A, (HL) + AND B + LD (HL), A + LD A, 0x0 + OUT (SYS_DD17PB), A + RET +edd_ep_fm_0 + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + LD A, 0x0 + OUT (SYS_DD17PB), A + RET +edd_ep_task_end + CALL get_pixel + LD (M_VARS.esc_var3), A + RET + +; -------------------------------------------------- +; +; -------------------------------------------------- +esc_picture: + LD HL, (M_VARS.esc_param+3) + LD A, (HL) + CP ':' + RET NZ + INC HL + LD E, (HL) + INC HL + LD D, (HL) + INC HL + LD A, (HL) + LD (M_VARS.esc_var0), A + INC HL + LD A, (HL) + LD (M_VARS.esc_var1), A + INC HL + PUSH HL + LD C, (HL) + INC HL + LD B, (HL) + INC HL + INC HL + EX DE, HL + PUSH DE + + ; Enable VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + CALL pict_sub1 + ; Disable VRAM access + LD A, 0x0 + OUT (SYS_DD17PB), A + + POP DE + POP HL + LD (HL), C + INC HL + LD (HL), B + CALL pict_sub2 ; TODO: replace call+ret to jp; + RET + +pict_sub1: + LD A, (M_VARS.esc_param) + CP ASCII_EM + JP Z, gih_up + CP ASCII_CAN + JP Z, gih_rt + CP ASCII_SUB + JP Z, gih_ctrl_z + CP ASCII_BS + JP Z, gih_bs + CP ASCII_US + JP Z, pict_clr + RET + +pict_clr: + LD L, C + LD H, B + LD A, (M_VARS.esc_var0) + LD C, A + LD A, (M_VARS.esc_var1) + LD B, A + CALL put_image + POP HL + POP HL + POP HL + RET + +ehd_l1: + CP 0x2 + JP Z, get_image_hdr + CP 0x3 + JP Z, m_fn_39 + RET + +; -------------------------------------------------- +; Function 39 +; -------------------------------------------------- +m_fn_39: + LD HL, (M_VARS.esc_param+2) ; pr 3,4 + INC L + LD C, L + LD B, H + LD E, L + CALL dc_mul_e_h + ADD HL, HL + EX DE, HL + LD HL, (M_VARS.esc_param) ; par 1,2 + PUSH BC + PUSH DE + LD BC, 10 + LD E, L + LD D, H + ADD HL, BC + EX DE, HL + LD (HL), E + INC HL + LD (HL), D + INC HL + POP BC + LD A, 4 +.l1: + PUSH AF ; TODO: remove AF not changed + EX DE, HL + ADD HL, BC + EX DE, HL + LD (HL), E + INC HL + LD (HL), D + INC HL + POP AF ; TODO: remove AF not changed + DEC A + JP NZ, .l1 + EX DE, HL + LD HL, 0x0 + ADD HL, BC ; HL=BC + ADD HL, BC ; HL=2*BC + ADD HL, HL ; HL=4*BC + ADD HL, BC ; HL=5*BC + ADD HL, HL ; HL=10*BC + EX DE, HL ; DE=10*BC + LD A, 0x0 + LD B, A ; B=A=0 + ; fill DE bytes at [HL] with 0 +.l2: + LD (HL), B + INC HL + DEC DE + CP E + JP NZ, .l2 + CP D + JP NZ, .l2 + + XOR A + LD (M_VARS.esc_var0), A + POP BC + LD HL, (M_VARS.esc_param) + LD DE, 10 + ADD HL, DE +.l3: + EX DE, HL + LD HL, (M_VARS.esc_param+4) + EX DE, HL + PUSH BC + CALL fn39_sub2 + POP BC + LD A, (M_VARS.esc_var0) + ADD A, 0x2 + LD (M_VARS.esc_var0), A + CP 10 + RET Z + JP .l3 + +; --------------------------------------------------- +; Function 3C +; --------------------------------------------------- +get_image_hdr: + LD HL, (M_VARS.esc_param+4) + LD (HL), 58 ; ':' + INC HL + PUSH HL + LD HL, (M_VARS.esc_param+2) + INC L + LD C, L + LD A, H + ADD A, 0x4 + LD B, A + LD H, B + LD E, C + CALL dc_mul_e_h + ADD HL, HL + EX DE, HL + POP HL + LD (HL), E + INC HL + LD (HL), D + INC HL + LD (HL), C + INC HL + LD (HL), B + INC HL + EX DE, HL + LD HL, (M_VARS.esc_param) + ADD HL, HL + EX DE, HL + PUSH BC + PUSH HL + CALL calc_px_addr + POP DE + LD A, L + LD (DE), A + INC DE + LD A, H + LD (DE), A + INC DE + LD A, B + LD (DE), A + INC DE + POP BC + LD A, 0x1 + OUT (SYS_DD17PB), A + CALL get_image ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; = +; --------------------------------------------------- +esc_get_put_image: + LD A, (M_VARS.esc_param+6) + CP 0x2 + JP NC, ehd_l1 + LD HL, M_VARS.esc_param + LD E, (HL) + INC HL + LD D, (HL) + INC HL + LD C, (HL) + INC HL ; TODO: next call to calc_px_addr + LD B, (HL) ; destroy value of B and HL + CALL calc_px_addr + EX DE, HL + LD HL, (M_VARS.esc_param+4) + LD A, H + CP 128 + RET C + + CP 184 + RET NC + + EX DE, HL + + ; Enable VRAM access + LD A, 0x1 + OUT (SYS_DD17PB), A + LD A, (M_VARS.esc_param+6) + OR A + JP NZ, put_image + +; --------------------------------------------------- +; Get image from VRAM to user buffer +; Inp: HL -> VRAM[x,y] +; DE -> buffer +; BC - width, height +; --------------------------------------------------- +get_image: + PUSH HL + PUSH BC +.next_row: + ; byte 1 + LD A, (HL) + LD (DE), A + INC H ; next Y (row) + INC DE + ; byte 2 ; next dst addr + LD A, (HL) + LD (DE), A + INC H + LD A, H + CP 128 ; last row? + JP NZ, .l2 + LD H, 0x40 ; reset Y +.l2: + INC DE + DEC C + JP NZ, .next_row + POP BC + POP HL + INC L + DEC B ; dec width + JP NZ, get_image + JP img_task_end + +; --------------------------------------------------- +; Put image from buffer to VRAM +; Inp: HL -> VRAM[x,y] +; DE -> buffer +; BC - width, height +; --------------------------------------------------- +put_image: + PUSH HL + PUSH BC +.next_row: + ; two bytes for 8 pixels + ; byte 1 + LD A, (DE) ; get from buffer + LD (HL), A ; put to screen + INC H ; next Y (row) + INC DE ; next src addr + ; byte 2 + LD A, (DE) + LD (HL), A + INC DE + INC H + LD A, H + CP 128 ; last row? + JP NZ, .l2 + LD H, 0x40 ; reset +.l2: + DEC C + JP NZ, .next_row + POP BC + POP HL + ; next column + INC L + DEC B + JP NZ, put_image + +img_task_end: + LD A, 0x0 + OUT (SYS_DD17PB), A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +fn39_sub2: + DEC C +.l1: + PUSH BC +.l2: + EX DE, HL + PUSH BC + PUSH HL + LD L, (HL) + LD H, 0x0 + LD A, (M_VARS.esc_var0) + LD B, A + OR A + JP Z, .l4 +.l3: + ADD HL, HL + DEC A + JP NZ, .l3 +.l4: + LD A, B + LD C, L + LD B, H + POP HL + INC HL + PUSH HL + LD L, (HL) + LD H, 0x0 + OR A + JP Z, .l6 +.l5: + ADD HL, HL + DEC A + JP NZ, .l5 +.l6: + EX DE, HL + LD A, (HL) + OR C + LD (HL), A + INC HL + LD A, (HL) + OR E + LD (HL), A + INC HL + LD (HL), B + INC HL + LD (HL), D + DEC HL + POP DE + INC DE + POP BC + DEC C + JP NZ, .l2 + POP BC + INC HL + INC HL + DEC B + JP NZ, .l1 + RET + +; -------------------------------------------------- +; Handle ASCII_CAN symbol (cursor right) +; -------------------------------------------------- +gih_rt: + DEC DE + LD A, (DE) + ADD A, 0x2 + LD (DE), A + CP 9 + RET C + LD A, 0x2 + LD (DE), A + INC DE + PUSH BC + LD H, D + LD L, E + INC HL + INC HL + LD A, (M_VARS.esc_var0) + PUSH AF + DEC A + LD (M_VARS.esc_var0), A + INC A + ADD A, A + ADD A, B + CP 128 + JP C, .l1 + SUB 0x40 +.l1: + LD B, A + LD A, (M_VARS.esc_var1) +.l2: + PUSH AF + LD A, (M_VARS.esc_var0) +.l3: + PUSH AF + LD A, (HL) + LD (DE), A + INC HL + INC DE + LD A, (HL) + LD (DE), A + INC HL + INC DE + POP AF + DEC A + JP NZ, .l3 + LD A, (BC) + LD (DE), A + INC DE + INC HL + INC B + LD A, (BC) + LD (DE), A + INC HL + INC DE + DEC B + INC C + POP AF + DEC A + JP NZ, .l2 + POP AF + LD (M_VARS.esc_var0), A + POP BC + INC B + INC B + LD A, B + CP 0x80 + RET NZ + LD B, 0x40 + RET + +; -------------------------------------------------- +; Handle ASCII_BS (BackSpace) symbol +; -------------------------------------------------- +gih_bs: + DEC DE + LD A, (DE) + SUB 0x2 + LD (DE), A + RET NC + + LD A, 6 + LD (DE), A + INC DE + PUSH BC + ADD HL, DE + DEC HL + LD D, H + LD E, L + DEC HL + DEC HL + LD A, (M_VARS.esc_var1) + ADD A, C + DEC A + LD C, A + LD A, B + DEC A + CP 0x3f + JP NZ, .l1 + LD A, 0x7f ; [DEL]? +.l1: + LD B, A + LD A, (M_VARS.esc_var0) + PUSH AF + DEC A + LD (M_VARS.esc_var0), A + LD A, (M_VARS.esc_var1) +.l2: + PUSH AF + LD A, (M_VARS.esc_var0) +.l3: + PUSH AF + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + POP AF + DEC A + JP NZ, .l3 + LD A, (BC) + LD (DE), A + DEC HL + DEC DE + DEC B + LD A, (BC) + LD (DE), A + DEC HL + DEC DE + INC B + DEC C + POP AF + DEC A + JP NZ, .l2 + POP AF + LD (M_VARS.esc_var0), A + POP BC + DEC B + DEC B + LD A, B + CP 0x3e + RET NZ + LD B, 0x7e + RET + +; -------------------------------------------------- +; Handle ASCII_SUB symbol +; -------------------------------------------------- +gih_ctrl_z: + PUSH BC + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, A + ADD A, E + LD L, A + LD H, D + LD A, (M_VARS.esc_var1) + ADD A, C + LD C, A + PUSH BC + LD A, (M_VARS.esc_var1) + DEC A + DEC A + LD C, A +.l1: + LD A, (M_VARS.esc_var0) + LD B, A +.l2: + LD A, (HL) + LD (DE), A + INC HL + INC DE + LD A, (HL) + LD (DE), A + INC HL + INC DE + DEC B + JP NZ, .l2 + DEC C + JP NZ, .l1 + POP BC + LD L, 0x2 +.l3: + LD A, (M_VARS.esc_var0) + LD H, A + PUSH BC +.l4: + LD A, (BC) + LD (DE), A + INC DE + INC B + LD A, (BC) + LD (DE), A + INC DE + INC B + LD A, B + CP 0x80 + JP NZ, .l5 + LD B, 0x40 +.l5: + DEC H + JP NZ, .l4 + POP BC + INC C + DEC L + JP NZ, .l3 + POP BC + INC C + INC C + RET + +; -------------------------------------------------- +; Handle ASCII_EM symbol +; -------------------------------------------------- +gih_up: + PUSH BC + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, B + CP 128 + JP Z, .l1 + JP C, .l1 + SUB 64 +.l1: + DEC A + LD B, A + DEC C + PUSH BC + ADD HL, DE + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, A + LD E, A + LD A, L + SUB E + LD E, A + LD D, H + DEC DE + DEC HL + EX DE, HL + LD A, (M_VARS.esc_var1) + DEC A + DEC A + LD C, A +.l2: + LD A, (M_VARS.esc_var0) + LD B, A +.l3: + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + LD A, (HL) + LD (DE), A + DEC HL + DEC DE + DEC B + JP NZ, .l3 + DEC C + JP NZ, .l2 + POP BC + LD L, 0x2 + +.l4: + LD A, (M_VARS.esc_var0) + LD H, A + PUSH BC + +.l5: + LD A, (BC) + LD (DE), A + DEC DE + DEC B + LD A, (BC) + LD (DE), A + DEC DE + DEC B + LD A, B + CP 0x3f + JP NZ, .l6 + LD B, 0x7f + +.l6: + DEC H + JP NZ, .l5 + POP BC + DEC C + DEC L + JP NZ, .l4 + POP BC + DEC C + DEC C + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +pict_sub2: + PUSH DE + DEC DE + LD A, (DE) + LD E, A + LD D, 0x0 + LD HL, (M_VARS.esc_param+1) + ADD HL, DE + LD E, (HL) + INC HL + LD D, (HL) + POP HL + PUSH BC + PUSH HL + PUSH HL + LD HL, (M_VARS.esc_param+3) + INC HL + LD C, (HL) + INC HL + LD B, (HL) + POP HL + ADD HL, BC + LD C, L + LD B, H + POP HL + CALL mov_hl_bc + LD A, (M_VARS.esc_param+5) + OR A + JP Z, .l1 + EX DE, HL +.l1: + LD A, (M_VARS.esc_var1) + SUB 0x4 +.l2: + PUSH AF + LD A, (M_VARS.esc_var0) +.l3: + PUSH AF + LD A, (DE) + INC DE + PUSH DE + PUSH AF + LD A, (DE) + LD E, A + POP AF + LD D, A + OR E + CPL + PUSH AF + AND (HL) + OR D + LD (BC), A + INC BC + INC HL + POP AF + AND (HL) + OR E + LD (BC), A + INC BC + INC HL + POP DE + INC DE + POP AF + DEC A + JP NZ, .l3 + POP AF + DEC A + JP NZ, .l2 + LD A, (M_VARS.esc_param+5) + OR A + JP Z, .l4 + EX DE, HL +.l4: + CALL mov_hl_bc + POP DE + EX DE, HL + LD A, (M_VARS.esc_var0) + LD C, A + LD A, (M_VARS.esc_var1) + LD B, A + LD A, 0x1 + OUT (SYS_DD17PB), A + CALL put_image ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Move form [HL] to [BC] count of bytes +; Inp: HL -> src +; BC -> dst +; esc_var0*4 - count +; --------------------------------------------------- +mov_hl_bc: + PUSH DE + LD A, (M_VARS.esc_var0) + ADD A, A + ADD A, A + LD E, A ; E = param * 4 + ; move [HL] -> [BC] E bytes +.next: + LD A, (HL) + LD (BC), A + INC HL + INC BC + DEC E + JP NZ, .next + POP DE + RET + +; --------------------------------------------------- +; Draw circle +; Inp: param x,y,radius, aspect_x, aspect_y +; --------------------------------------------------- +esc_draw_circle: + LD A, (M_VARS.esc_param+2) ; radius + LD B, A + OR A + RET Z ; exit ir radius 0 + LD A, 0x7f + CP B + RET M ; exit if radius>127 + + XOR A + LD D, A ; 0 + LD E, B ; r + CALL dc_draw_8px + + LD A, 1 + LD H, A + SUB B + LD C, A + LD A, B + RLCA + LD B, A + LD A, 0x1 + SUB B + LD L, A + CCF ; TODO: unused +.l1: + INC D + LD A, E + CP D + JP Z, dc_draw_8px + CALL dc_draw_8px + LD A, H + ADD A, 0x2 + LD H, A + LD A, L + ADD A, 0x2 + LD L, A + LD A, C + ADD A, H + LD C, A + JP NC, .l1 +.l2: + CCF ; TODO: unused + INC D + DEC E + LD A, D + CP E + JP Z, dc_draw_8px + SUB E + CP 0x1 + RET Z + LD A, E + SUB D + CP 0x1 + JP Z, dc_draw_8px + CALL dc_draw_8px + LD A, H + ADD A, 0x2 + LD H, A + LD A, L + ADD A, 0x4 + LD L, A + JP NC, .l3 + CCF ; TODO: unused +.l3: + LD A, C + ADD A, L + LD C, A + JP NC, .l1 + JP .l2 + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_8px: + PUSH HL + PUSH DE + PUSH BC + PUSH DE + CALL dc_aspect_ratio_1 + LD HL, (M_VARS.esc_param) ; HL=Y,X + CALL dc_draw_4px_bc + POP DE + CALL dc_aspect_ratio2 + LD HL, (M_VARS.esc_param) ; HL=Y,X + CALL dc_draw_4px_cb + POP BC + POP DE + POP HL + XOR A + RET + +; --------------------------------------------------- +; Scale circle axis dy specified aspect ratio +; if aspect_x = 0 C = D else C = D * aspect_x / 256 +; if aspect_y = 0 B = E else B = E * aspect_y / 256 +; --------------------------------------------------- +dc_aspect_ratio_1: + LD HL, (M_VARS.esc_param+3) ; aspect_x -> L, aspect_y -> H + LD A, L + OR A + LD C, D + LD B, E + JP NZ, .dc_ax_ne0 + LD A, H + OR A + JP NZ, .dc_ay_ne0 + RET +.dc_ax_ne0: + LD A, H + LD H, L + LD E, C + CALL dc_mul_e_h + LD C, E + OR A + RET Z +.dc_ay_ne0: + LD H, A + LD E, B + CALL dc_mul_e_h + LD B, E + RET + +; --------------------------------------------------- +; if aspect_x = 0 B = E else B = E * aspect_x / 256 +; if aspect_y = 0 C = D else C = D * aspect_y / 256 +; --------------------------------------------------- +dc_aspect_ratio2: + LD HL, (M_VARS.esc_param+3) ; aspect_x -> L, aspect_y -> H + LD A, L + OR A + LD C, D + LD B, E + JP NZ, .dc_ax_ne0 + LD A, H + OR A + JP NZ, .dc_ay_ne0 + RET +.dc_ax_ne0: + LD A, H + LD H, L + LD E, B + CALL dc_mul_e_h + LD B, E + OR A + RET Z + +.dc_ay_ne0: + LD H, A + LD E, C + CALL dc_mul_e_h + LD C, E + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_mul_e_h: + LD D, 0x0 + LD L, D + ADD HL, HL + JP NC, .l1 + ADD HL, DE +.l1: + ADD HL, HL + JP NC, .l2 + ADD HL, DE +.l2: + ADD HL, HL + JP NC, .l3 + ADD HL, DE +.l3: + ADD HL, HL + JP NC, .l4 + ADD HL, DE +.l4: + ADD HL, HL + JP NC, .l5 + ADD HL, DE +.l5: + ADD HL, HL + JP NC, .l6 + ADD HL, DE +.l6: + ADD HL, HL + JP NC, .l7 + ADD HL, DE +.l7: + ADD HL, HL + JP NC, .l8 + ADD HL, DE +.l8: + LD E, H + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_4px_bc: + ; draw pixel(H+B, L+C) if in screen + LD A, H + ADD A, B + JP C, .l1 + LD D, A + LD A, L + ADD A, C + LD E, A + CALL dc_put_pixel +.l1: + ; draw pixel(H+B, L-C) if in screen + LD A, H + ADD A, B + JP C, .l2 + LD D, A + LD A, L + SUB C + LD E, A + CALL dc_put_pixel +.l2: + ; draw pixel(H-B, L-C) if in screen + LD A, H + SUB B + JP C, .l3 + LD D, A + LD A, L + SUB C + LD E, A + CALL dc_put_pixel +.l3: + ; draw pixel(H-B, L+C) if in screen + LD A, H + SUB B + RET C + LD D, A + LD A, L + ADD A, C + LD E, A + CALL dc_put_pixel ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +dc_draw_4px_cb: + ; draw pixel(H+C, L+B) if in screen + LD A, H + ADD A, C + JP C, .l1 + LD D, A + LD A, L + ADD A, B + LD E, A + CALL dc_put_pixel +.l1: + ; draw pixel(H+C, L-B) if in screen + LD A, H + ADD A, C + JP C, .l2 + LD D, A + LD A, L + SUB B + LD E, A + CALL dc_put_pixel +.l2: + ; draw pixel(H-C, L-B) if in screen + LD A, H + SUB C + JP C, l3 + LD D, A + LD A, L + SUB B + LD E, A + CALL dc_put_pixel +l3: + ; draw pixel(H-C, L+B) if in screen + LD A, H + SUB C + RET C + LD D, A + LD A, L + ADD A, B + LD E, A + CALL dc_put_pixel ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Draw pixel on screen +; Inp: DE - X, Y +; --------------------------------------------------- +dc_put_pixel: + RET C ; return if CF set (out of screen) + PUSH HL + PUSH BC + CALL calc_px_addr + ; calculate B = pixel mask + LD A, 10000000b +.roll: + RLCA ; [07654321] <- [76547210], [7] -> CF + DEC B + JP P, .roll + CPL + LD B, A + ; DE = foreground color low and hi bytes + EX DE, HL + LD HL, (M_VARS.curr_color) + EX DE, HL + ; Turn on Video RAM + LD A, 0x1 + OUT (SYS_DD17PB), A + ; Load VRAM[HL] byte (low byte), mask and set + LD A, (HL) + XOR E + AND B + XOR E + LD (HL), A + ; Load VRAM[HL+1] byte (low byte), mask and set + INC H + LD A, (HL) + XOR D + AND B + XOR D + LD (HL), A + ; Turn off Video RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + POP BC + POP HL + RET + + ; Full charset, Common + Latin letters (112*8=890) + INCLUDE "font-6x7.inc" + +; --------------------------------------------------- +; Convert 0h..Fh decimal value to symbol '0'..'F' +; --------------------------------------------------- +conv_nibble: + AND 0xf + ADD A, 0x90 + DAA + ADC A, 0x40 + DAA + LD C, A + RET + +; --------------------------------------------------- +; Print byte in HEX +; Inp: A - byte to print +; --------------------------------------------------- +m_hexb: + PUSH AF + RRCA + RRCA + RRCA + RRCA + CALL out_hex + POP AF + +out_hex: + CALL conv_nibble + CALL m_con_out ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Wtite RAM-Disk 64K to TAPE +; --------------------------------------------------- +m_tape_write_ram2: + LD HL, M_VARS.buffer + LD C, 128 +.cl_stack: + LD (HL), 0x0 + INC HL + DEC C + JP NZ, .cl_stack + LD HL, M_VARS.buffer + LD DE, 0xffff + ; write empty block + ; DE - block ID + ; HL -> block + CALL m_tape_write + CALL twr2_delay + LD DE, 0x0 + CALL m_tape_write + CALL twr2_delay + LD BC, 512 + LD DE, 0x0 +.nxt_blk: + PUSH BC + LD HL, M_VARS.buffer + CALL m_ramdisk_read + INC DE + CALL m_tape_write + CALL twr2_delay + POP BC + DEC BC + LD A, B + OR C + JP NZ, .nxt_blk + RET + +; --------------------------------------------------- +; Pause between blocks on tape +; --------------------------------------------------- +twr2_delay: + LD BC, 250 +.delay: + DEC BC + LD A, B + OR C + JP NZ, .delay + RET + +; --------------------------------------------------- +; Read RAM-Disk 64K from TAPE +; --------------------------------------------------- +m_tape_read_ram2: + LD A, 100 + CALL m_tape_wait + OR A + JP NZ, .end + LD E, 6 + +.srch_first: + DEC E + JP Z, .not_found + ; read block + LD HL, M_VARS.buffer + CALL m_tape_read + CP 4 + JP Z, .end + OR A + JP NZ, .srch_first + LD A, B + OR C + JP NZ, .srch_first + + LD BC, 512 + LD DE, 0x0 + +.rd_next: + PUSH BC + ; Read block from tape + CALL m_tape_read + OR A + JP NZ, .rd_error + DEC BC + LD A, B + CP D + JP NZ, .inv_id + LD A, C + CP E + JP NZ, .inv_id + ; Ok, write block to RAM disk + CALL m_ramdisk_write + INC DE + POP BC + DEC BC + LD A, B + OR C + JP NZ, .rd_next + RET +.not_found: + LD HL, msg_no_start_rec + CALL me_out_strz ; TODO: replace call+ret to jp + RET +.rd_error: + CP 2 + JP Z, .err_ubi + CP 4 + JP Z, .err_ibu + LD HL, msg_checksum + CALL me_out_strz + CALL out_hexw + POP BC + RET + + ; Illegal sequence of blocks +.inv_id: + LD HL, msg_sequence + CALL me_out_strz + INC BC + CALL out_hexw + POP BC + RET + +.err_ubi: + LD HL, msg_ibg + CALL me_out_strz + POP BC + RET + + ; Interrupted by user +.err_ibu: + POP BC +.end: + LD HL, msg_break + CALL me_out_strz ; TODO: replace call+ret to jp + RET + +; -------------------------------------------------- +; Output hex word +; Inp: BC - word to output +; -------------------------------------------------- +out_hexw: + PUSH BC + LD A, B + CALL m_hexb + POP BC + LD A, C + CALL m_hexb ; TODO: replace call+ret to jp + RET + +msg_no_start_rec: + DB "NO START RECORD", 0 +msg_checksum: + DB "CHECKSUM ", 0 +msg_sequence: + DB "SEQUENCE ", 0 +msg_ibg: + DB "IBG", 0 +msg_break: + DB "BREAK", 0 + +; --------------------------------------------------- +; Out ASCIIZ message +; Inp: HL -> zero ended string +; --------------------------------------------------- +me_out_strz: + LD A, (HL) + OR A + RET Z + PUSH BC + LD C, A + CALL m_con_out + INC HL + POP BC + JP me_out_strz + + + +; --------------------------------------------------- +; Read from RAM-disk to RAM +; Inp: DE - source sector +; HL -> destination buffer +; --------------------------------------------------- +m_ramdisk_read: + PUSH HL + PUSH DE + LD A, D + ; Build value to access ext RAM (A17, A16, 32k bits) + AND 00000001b ; Low 32K bits of memory mapper + OR 0x2 ; Calc A16 address lines + OR 0x0 ; TODO: nothing, remove + LD B, A ; B - value to turn on access to Ext RAM + ; Calculate DE = address from sector number + XOR A + LD A, E ; E - low address + RRA ; [CF] -> [7:0] -> [CF] + LD D, A ; D = E/2 + LD A, 0x0 + RRA ; [CF] -> E + LD E, A +.read: + ; Access to ExtRAM + LD A, B + OUT (SYS_DD17PB), A + ; Get Byte + LD A, (DE) + LD C, A + ; Access to RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + ; Set Byte + LD (HL), C + ; HL++, DE++ + INC HL + INC DE + LD A, E + ADD A, A + JP NZ, .read ; jump if has more bytes + + ; Access to RAM + LD A, 0x0 + OUT (SYS_DD17PB), A + + POP DE + POP HL + RET + +; --------------------------------------------------- +; Write sector to RAM disk +; Inp: HL -> source buffer +; DE - destination sector +; --------------------------------------------------- +m_ramdisk_write: + PUSH HL + PUSH DE + LD A, D + AND 0x1 + OR 0x2 ; build value to access ext RAM (A16, 32k bits) + OR 0x0 ; TODO: remove unused + LD B, A + XOR A + LD A, E + RRA + LD D, A + LD A, 0x0 + RRA + LD E, A +.wr_byte: + LD A, 0x0 + OUT (SYS_DD17PB), A + LD C, (HL) + LD A, B + OUT (SYS_DD17PB), A + LD A, C + LD (DE), A + INC HL + INC DE + LD A, E + ADD A, A + JP NZ, .wr_byte + LD A, 0x0 + OUT (SYS_DD17PB), A + POP DE + POP HL + RET + +; -------------------------------------------------- +; Write block to Tape +; In: DE - block ID, +; HL -> block of data. +; -------------------------------------------------- +m_tape_write: + PUSH HL + PUSH DE + PUSH DE + LD BC, 2550 + LD A, PIC_POLL_MODE ; pool mode + OUT (PIC_DD75RS), A + LD A,TMR0_SQWAVE ; tmr0, load lsb+msb, sq wave, bin + OUT (TMR_DD70CTR), A + LD A, C + OUT (TMR_DD70C1), A + LD A, B + OUT (TMR_DD70C1), A + ; Write Hi+Lo, Hi+Lo + LD DE, 4 ; repeat next 4 times +.l1: + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; check rst4 from timer#0 + JP NZ, .l1 + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH ; tape level hi + JP NZ, .set_lvl + LD A, TL_LOW ; tape level low +.set_lvl: + OUT (DD67PC), A ; set tape level + LD A, TMR0_SQWAVE ; tmr0, load lsb+msb, swq, bin + ; timer on + OUT (TMR_DD70CTR), A + LD A, C + OUT (TMR_DD70C1), A + LD A, B + OUT (TMR_DD70C1), A + DEC E + JP NZ, .l1 + +.l2: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .l2 + + ; Write 00 at start + LD A, 0x0 + CALL m_tape_wr_byte + ; Write 0xF5 marker + LD A, 0xf5 + CALL m_tape_wr_byte + LD E, 0x0 ; checksum=0 + ; Write block ID + POP BC + LD A, C + CALL m_tape_wr_byte + LD A, B + CALL m_tape_wr_byte + ; Write 128 data bytes + LD B, 128 +.next_byte: + LD A, (HL) + CALL m_tape_wr_byte + INC HL + DEC B + JP NZ, .next_byte + ; Write checksum + LD A, E + CALL m_tape_wr_byte + ; Write final zero byte + LD A, 0x0 + CALL m_tape_wr_byte +.wait_end: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .wait_end + LD A, TL_MID ; tape level middle + OUT (DD67PC), A + POP DE + POP HL + RET + + +; ------------------------------------------------------ +; Write byte to tape +; Inp: A - byte top write +; D - current level +; E - current checksum +; ------------------------------------------------------ +m_tape_wr_byte: + PUSH BC + ; calc checksum + LD B, A + LD A, E + SUB B + LD E, A + LD C, 8 ; 8 bit in byte +.get_bit: + LD A, B + RRA + LD B, A + JP C, .bit_hi +.wait_t: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .wait_t + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; program for 360 cycles + LD A, 0x68 + OUT (TMR_DD70C1), A + LD A, 0x1 + OUT (TMR_DD70C1), A + ; change amplitude + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH + JP NZ, .out_bit + LD A, TL_LOW +.out_bit: + OUT (DD67PC), A + DEC C + JP NZ,.get_bit + POP BC + RET +.bit_hi: + IN A, (PIC_DD75RS) + AND TIMER_IRQ + JP NZ, .bit_hi + ; program for 660 cycles + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + LD A, 0x94 + OUT (TMR_DD70C1), A + LD A, 0x2 + OUT (TMR_DD70C1), A + ; change amplitude + LD A, D + CPL + LD D, A + OR A + LD A, TL_HIGH + JP NZ, .out_bit_hi + LD A, TL_LOW +.out_bit_hi: + OUT (DD67PC), A + DEC C + JP NZ, .get_bit + POP BC + RET + +; ------------------------------------------------------ +; Load block from Tape +; In: HL -> buffer to receive bytes from Tape +; Out: A = 0 - ok, +; 1 - CRC error, +; 2 - unexpected block Id +; 4 - key pressed +; ------------------------------------------------------ +m_tape_read: + PUSH HL + PUSH DE + LD A, PIC_POLL_MODE ; pool mode + OUT (PIC_DD75RS), A + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A ; tmr0, load lsb+msb, sq wave + LD A, 0x0 + ; tmr0 load 0x0000 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + LD C, 3 +.wait_3_changes: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + LD A, B + ADD A, 4 + JP P, .wait_3_changes + DEC C + JP NZ, .wait_3_changes +.wait_4th_change: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + LD A, B + ADD A, 4 + JP M, .wait_4th_change + LD C, 0x0 +.wait_f5_marker: + CALL read_tape_bit_kbd + INC A + JP Z, .key_pressed + DEC A + RRA + LD A, C + RRA + LD C, A + CP 0xf5 + JP NZ, .wait_f5_marker + LD E, 0x0 ; checksum = 0 + ; Read blk ID + CALL m_tape_read_byte + JP NC, .err_read_id + LD C, D + CALL m_tape_read_byte + JP NC, .err_read_id + LD B, D + PUSH BC + ; Read block, 128 bytes + LD C, 128 +.read_next_b: + CALL m_tape_read_byte + JP NC, .err_read_blk + LD (HL), D + INC HL + DEC C + JP NZ, .read_next_b + + ; Read checksum + CALL m_tape_read_byte + JP NC, .err_read_blk + LD A, E + OR A + JP Z, .checksum_ok + LD A, 0x1 ; bad checksum +.checksum_ok: + POP BC +.return: + POP DE + POP HL + RET + +.err_read_blk: + POP BC + LD BC, 0x0 +.err_read_id: + LD A, 0x2 ; read error + JP .return +.key_pressed: + CALL m_con_in + LD C, A ; store key code in C + LD B, 0x0 + LD A, 0x4 + JP .return + +; ------------------------------------------------------ +; Read byte from Tape +; Out: D - byte +; CF is set if ok, cleared if error +; ------------------------------------------------------ +m_tape_read_byte: + PUSH BC + LD C, 8 +.next_bit: + CALL m_read_tape_bit + ; push bit from lo to hi in D + RRA + LD A, D + RRA + LD D, A + LD A, 4 + ADD A, B + JP NC, .ret_err + DEC C + JP NZ, .next_bit + ; calc checksum + LD A, D + ADD A, E + LD E, A + SCF +.ret_err: + POP BC + RET + +; ------------------------------------------------------ +; Read bit from tape +; Out: A - bit from tape +; B - time from last bit +; ------------------------------------------------------ +m_read_tape_bit: + IN A, (KBD_DD78PB) ; Read Tape bit 5 (data) + AND TAPE_P + LD B, A +.wait_change: + IN A, (KBD_DD78PB) + AND TAPE_P + CP B + JP Z, .wait_change + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; [360...480...660] 0x220=544d + IN A, (TMR_DD70C1) ; get tmer#0 lsb + ADD A, 0x20 + IN A, (TMR_DD70C1) ; get tmer#0 msb + LD B, A + ADC A, 0x2 + ; reset timer to 0 + LD A, 0x0 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + ; For 0 - 65535-360+544 -> overflow P/V=1 + ; For 1 - 65535-660+544 -> no overflow P/V=0 + RET P + INC A + RET + +; ------------------------------------------------------ +; Read bit from tape with keyboard interruption +; Out: A - bit from tape +; B - time from last bit +; ------------------------------------------------------ +read_tape_bit_kbd: + IN A, (KBD_DD78PB) + AND TAPE_P + LD B, A ; save tape bit state + ; wait change with keyboard check +.wait_change: + IN A, (PIC_DD75RS) + AND KBD_IRQ + JP NZ, .key_pressed + IN A, (KBD_DD78PB) + AND TAPE_P + CP B + JP Z, .wait_change + ; measure time + LD A, TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; read lsb+msb + IN A, (TMR_DD70C1) + ADD A, 0x20 + IN A, (TMR_DD70C1) + LD B, A + ADC A, 0x2 + ; reset timer#0 + LD A, 0x0 + OUT (TMR_DD70C1), A + OUT (TMR_DD70C1), A + ; flag P/V is set for 0 + RET P + INC A + RET +.key_pressed: + LD A, 0xff + RET + +; ------------------------------------------------------ +; Wait tape block +; Inp: A - periods to wait +; Out: A=4 - interrupded by keyboard, C=key +; ------------------------------------------------------ +m_tape_wait: + OR A + RET Z + PUSH DE + LD B, A +.wait_t4: + LD C,B + IN A, (KBD_DD78PB) + AND TAPE_P ; Get TAPE4 (Wait det) and save + LD E, A ; store T4 state to E +.wait_next_2ms: + LD A,TMR0_SQWAVE + OUT (TMR_DD70CTR), A + ; load 3072 = 2ms + XOR A + OUT (TMR_DD70C1), A + LD A, 0xc + OUT (TMR_DD70C1), A +.wait_tmr_key: + IN A, (PIC_DD75RS) + AND KBD_IRQ ; RST1 flag (keyboard) + JP NZ, .key_pressed + IN A, (PIC_DD75RS) + AND TIMER_IRQ ; RST4 flag (timer out) + JP Z, .wait_no_rst4 + IN A, (KBD_DD78PB) + AND TAPE_P ; TAPE4 not changed? + CP E + JP NZ, .wait_t4 ; continue wait + JP .wait_tmr_key +.wait_no_rst4: + DEC C + JP NZ, .wait_next_2ms + XOR A + POP DE + RET + +.key_pressed: + CALL m_con_in + LD C, A ; C = key pressed + LD A, 0x4 ; a=4 interrupted by key + POP DE + RET + +; ------------------------------------------------------ +; Check block marker from Tape +; Out: A=0 - not detected, 0xff - detected +; ------------------------------------------------------ +m_tape_blk_detect: + IN A, (KBD_DD78PB) + AND TAPE_D ; TAPE5 - Pause detector + LD A, 0x0 + RET Z + CPL + RET + +; ====================================================== +; FDC DRIVER +; ====================================================== + + +fdc_unload_head: + LD A, 0x0 + OUT (FDC_DATA), A + LD A, FDC_RESTORE_UH_NV + OUT (FDC_CMD), A + NOP + NOP + +.wait_no_busy: + IN A, (FDC_CMD) + AND 00000101b ; Track0 , Busy + CP 00000100b + JP Z, .tr0_ok + + IN A, (FLOPPY) + RLCA ; MOTST -> CF + JP NC, .wait_no_busy + LD A, 0x20 + RET +.tr0_ok: + LD A, B + DEC A + LD A, 0x1 + JP Z, .b1 + LD (M_VARS.ul_A_var1), A + XOR A + LD (M_VARS.ul_A_var4), A + RET + +.b1: + LD (M_VARS.ul_B_var2), A + XOR A + LD (M_VARS.ul_B_var5), A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_select_drive: + PUSH AF + CALL delay_1.4mS + CP 0x1 ; TODO: DEC A to save 1b 3t + JP Z, .sel_A + LD A, 0x2 + JP .sel_B +.sel_A + LD A, 0x5 +.sel_B + LD B, A ; 010b or 101b + IN A, (FLOPPY) ; read Floppy controller reg + AND 0x40 ; SSEL + RRA ; SSEL for out + OR B ; 0x22 or 0x25 if WP + OUT (FLOPPY), A ; Select drive A or B + LD B, A + POP AF + DEC A + JP Z, .dpar_a + LD A, (bios_var2) + JP .dpar_b +.dpar_a + LD A, (BIOS.bios_var04) +.dpar_b + PUSH BC + LD B, A ; B = dpar_A or B + LD A, D ; compare with D? + CP B + JP C, .l_le ; D < B + SUB B + LD D, A + POP BC + LD A, C + OR 0x8 + LD C, A + LD A, B + AND 0x20 + OR A + RET NZ + LD A, B + OR 0x20 ; set SSEL to 1 + OUT (FLOPPY), A + CALL delay_136uS + RET +.l_le + POP BC + LD A, B + AND 0x20 + OR A + RET Z + LD A, B + AND 0x7 + OUT (FLOPPY), A + CALL delay_136uS + RET + +; --------------------------------------------------- +; Delay for 136uS +; --------------------------------------------------- +delay_136uS: + LD B, 16 ; 7 + +; --------------------------------------------------- +; Delay for B*8uS +; --------------------------------------------------- +delay_b: + DEC B ; 4 + JP NZ, delay_b ; 10 + RET ; 10 + +; --------------------------------------------------- +; Delay for 1.4mS +; --------------------------------------------------- +delay_1.4mS: + LD B, 175 ; 7 + JP delay_b ; 10 + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_read_floppy: + PUSH AF + CALL m_select_drive + POP AF + CALL m_start_seek_track + JP C, fdc_ret + CALL m_fdc_read_c_bytes + JP C, fdc_ret + XOR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_write_floppy: + PUSH AF + CALL m_select_drive + POP AF + CALL m_start_seek_track + JP C, fdc_ret + CALL m_fdc_write_bytes + JP C, fdc_ret + XOR A + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_start_seek_track: + CALL m_start_floppy + RET C + CALL m_fdc_seek_trk + RET C + RET ; TODO: remove + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_start_floppy: + LD B, A + LD A, (M_VARS.ul_var3) + CP B + JP Z, .need_m_start + CALL .wait_motor ; TODO: replace call+ret to jp + RET +.need_m_start: + IN A, (FLOPPY) + RLCA ; check MOTST + JP C, .wait_motor + IN A, (FDC_CMD) + AND FDC_NOT_READY ; not ready flag + RET Z + +; --------------------------------------------------- +; +; --------------------------------------------------- +.wait_motor: + PUSH BC + LD BC, 65535 + CALL fdc_init +.wait_rdy1: + IN A, (FDC_CMD) + AND FDC_NOT_READY + JP Z, .long_delay + IN A, (FLOPPY) + RLCA ; CF<-A[7] MOTST flag + JP NC, .wait_rdy1 + LD A, 0x20 + JP .mst_exi +.long_delay: + DEC BC + LD A, B + OR A + JP NZ, .long_delay +.mst_exi: + POP BC + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +fdc_init: + IN A, (FLOPPY) + AND 01001110b ; Get SSEL, DRSEL, MOT1, MOT0 + RRA + OUT (FLOPPY), A + OR 0x08 ; Set INIT bit + OUT (FLOPPY), A + RET + +; --------------------------------------------------- +; Seek track on floppy +; Inp: DE - track/sector +; --------------------------------------------------- +m_fdc_seek_trk: + LD A, B + DEC A + JP Z, .drv_b + LD A, (M_VARS.ul_A_var1) + OR A + CALL Z, fdc_unload_head + RET C + LD A, (M_VARS.ul_A_var4) + OUT (FDC_TRACK), A + LD A, D + LD (M_VARS.ul_A_var4), A + JP .cmn +.drv_b: + LD A, (M_VARS.ul_B_var2) + OR A + CALL Z, fdc_unload_head + RET C + LD A, (M_VARS.ul_B_var5) + OUT (FDC_TRACK), A + LD A, D + LD (M_VARS.ul_B_var5), A +.cmn: + LD A, (M_VARS.ul_var3) + CP B + LD A, B + LD (M_VARS.ul_var3), A + JP NZ, .l2 + IN A, (FDC_TRACK) + CP D + JP Z, .l2 + JP C, .l1 + LD A, (M_VARS.ul_var6) + OR A + JP NZ, .l2 + LD B, 0xff + CALL delay_b + LD A, 0x1 + LD (M_VARS.ul_var6), A + JP .l2 +.l1: + LD A, (M_VARS.ul_var6) + OR A + JP Z, .l2 + LD B, 0xff + CALL delay_b + LD A, 0x0 + LD (M_VARS.ul_var6), A +.l2: + LD A, D + OUT (FDC_DATA), A + LD A, 0x1f + OUT (FDC_CMD), A + NOP + NOP + IN A, (FDC_WAIT) + IN A, (FDC_CMD) + AND 0x19 + CP 0x0 + JP NZ, .l3 + JP .l4 +.l3: + SCF + LD A, 0x40 +.l4: + PUSH AF + LD A, E + OUT (FDC_SECT), A + POP AF + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_fdc_write_bytes: + LD A, C + OUT (FDC_CMD), A +.w_next: + IN A, (FDC_WAIT) + RRCA + LD A, (HL) + OUT (FDC_DATA), A + INC HL + JP C, .w_next + CALL fdc_check_status ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; +; --------------------------------------------------- +m_fdc_read_c_bytes: + LD A, C + OUT (FDC_CMD), A + JP .l2 +.l1: + LD (HL), A + INC HL +.l2: + IN A, (FDC_WAIT) + RRCA + IN A, (FDC_DATA) + JP C, .l1 + CALL fdc_check_status ; TODO: replace call+ret to jp + RET + +; --------------------------------------------------- +; Check fdc status for errors +; Out: CF set if errors +; --------------------------------------------------- +fdc_check_status: + IN A, (FDC_CMD) + AND 11011111b + CP 0x0 + JP Z, fdc_ret + SCF +fdc_ret: + RET + +filler1: + DB 20h + +; filler: +; ds 169, 0xff + +; ------------------------------------------------------ + +LAST EQU $ +CODE_SIZE EQU LAST-0xE000 +FILL_SIZE EQU ROM_CHIP_SIZE-CODE_SIZE + + + ASSERT m_hot_start = 0xe051 + ASSERT m_out_strz = 0xe0f1 + ASSERT m_con_out_int = 0xe16d + ASSERT get_esc_param = 0xe187 + ASSERT esc_params_tab = 0xe1cb + ASSERT esc_handler_tab = 0xe1db + ASSERT esc_set_beep = 0xe1f9 + ASSERT m_print_hor_line = 0xe23a + ASSERT m_get_7vpix = 0xe2b4 + ASSERT esc_set_palette = 0xe2fe + ASSERT m_get_glyph = 0xe320 + ASSERT m_print_no_esc = 0xe349 + ASSERT calc_addr_40 = 0xe439 + ASSERT mp_mode_64 = 0xe4b8 + ASSERT calc_addr_80 = 0xe612 + ASSERT m_clear_screen = 0xe639 + ASSERT m_cursor_home = 0xe66c + ASSERT m_draw_cursor = 0xe69a + ASSERT m_handle_esc_code = 0xe77c + ASSERT handle_cc_common = 0xe7c4 + ASSERT handle_cc_80x25 = 0xe833 + ASSERT m_beep = 0xe85a + ASSERT esc_set_cursor = 0xe890 + ASSERT esc_set_vmode = 0xe8e9 + ASSERT esc_set_color = 0xe92f + ASSERT m_print_at_xy = 0xe943 + ASSERT game_sprite_tab = 0xea39 + ASSERT esc_draw_fill_rect = 0xeb64 + ASSERT draw_line_h = 0xeed1 + ASSERT esc_draw_line = 0xef0b + ASSERT esc_draw_dot = 0xf052 + ASSERT esc_picture = 0xf0a4 + ASSERT m_fn_39 = 0xf10f + ASSERT get_image_hdr = 0xf177 + ASSERT esc_get_put_image = 0xf1b5 + ASSERT pict_sub2 = 0xf3ca + ASSERT m_font_cp0 = 0xf5bc + ASSERT me_out_strz = 0xfb36 + ASSERT m_ramdisk_write = 0xfb6d + ASSERT m_tape_write = 0xfb97 + ASSERT m_tape_wr_byte = 0xfc0e + ASSERT m_tape_read_byte = 0xfcee + ASSERT m_read_tape_bit = 0xfd08 + ASSERT m_tape_wait = 0xfd58 + + + ; DISPLAY "Code size is: ", /A, CODE_SIZE + + +FILLER + DS FILL_SIZE, 0xFF + ; DISPLAY "Free size is: ", /A, FILL_SIZE + + ENDMODULE + + OUTEND + + OUTPUT m_vars.bin + ; put in separate waste file + INCLUDE "m_vars.inc" + OUTEND diff --git a/MON_r8_bedc54ad/ram.inc b/MON_r8_bedc54ad/ram.inc new file mode 100644 index 0000000..8c6c08e --- /dev/null +++ b/MON_r8_bedc54ad/ram.inc @@ -0,0 +1,49 @@ +; ======================================================= +; Ocean-240.2 +; +; RAM area at address: 0x0000 - 0x0100, used by CP/M and +; HW-Monitor +; By Romych 2026-02-03 +; ======================================================= + + IFNDEF _RAM + DEFINE _RAM + + MODULE RAM + +@warm_boot EQU 0x0000 ; Jump warm_boot (Restart) +@warm_boot_addr EQU 0x0001 ; address of warm boot entry point +@iobyte EQU 0x0003 ; Input/Output mapping +@cur_user_drv EQU 0x0004 ; [7:4] - curent user, [3:0] - current drive +@jp_bdos_enter EQU 0x0005 ; Jump bdos (CALL 5 to make CP/M requests) +@bdos_ent_addr EQU 0x0006 ; addres of BDOS entry point +@RST1 EQU 0x0008 +@RST1_handler_addr EQU 0x0009 +;RST2 EQU 0x0010 +;RST3 EQU 0x0018 +;RST4 EQU 0x0020 +;RST5 EQU 0x0028 +;RST6 EQU 0x0030 +;RST7 EQU 0x0038 +;reserve1 EQU 0x003b +@bios_var0 EQU 0x0040 ; 0xaa - bios init r8 +@bios_var1 EQU 0x0041 ; 0xaa - bios init r8 +@bios_var2 EQU 0x0042 ; 0x00 - bios init r8 +@bios_var3 EQU 0x0043 ; 0xff - bios init r8 +@interleave_0 EQU 0x0044 +;reserve2 EQU 0x0050 +@fcb1 EQU 0x005c ; Default FCB, 16 bytes +@fcb2 EQU 0x006c +;NMI_ISR EQU 0x0066 + +@dma_buffer EQU 0x0080 ; Default "DMA" 128 bytes buffer +@p_cmd_line_len EQU 0x0080 ; command line character count +@p_cmd_line EQU 0x0081 ; command line buffer +@fcb_ra_record_num EQU 0x00a1 +@bios_stack EQU 0x0100 +@tpa_start EQU 0x0100 ; start of program +@video_ram EQU 0x4000 + + ENDMODULE + + ENDIF \ No newline at end of file diff --git a/MON_r8_c4eec374/.gitignore b/MON_r8_c4eec374/.gitignore deleted file mode 100644 index b626b35..0000000 --- a/MON_r8_c4eec374/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.labels -*.obj -*.OBJ -*.bin -*.tmp -tmp/ -build/ -*.lst -*.sld -