From 97c361af9c236f65d4345b48efcbe68b38b75bae Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 3 Sep 2019 18:44:17 +0200 Subject: [PATCH 1/9] fixed EOI reporting to IEC devices --- bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_mega65.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes c64/kernal/iec/iec_tx_byte.s | 2 ++ 4 files changed, 2 insertions(+) diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index 67a92cbceaaebd3eb53764694f4e9c9ec8652b8a..a1e4bfcf490abc4a6c40174b97c6c44f0541c4cc 100644 GIT binary patch delta 663 zcmXYuUr19?9LMh;H$yP*R$JG|`aPKG6cy<~2&eRt$?rj85E8gcT3GC%hlHNW!f6P? zm9unMk&G?2NVv2fwn2spDFbDX1w}oW4~A2>dyYb-ojZE@o!{a6#aShAElW@OR>QgBwq!0tqMxck@xxKQN2kYW+X zyztGVRAqDfP+f#W3U8T3^h;?J56LOVjKWvRkf*U(D0MnnaNH8(q}F-c-EY>T&lDg` zjmzA?8aM-fGUrtJK-#(T$jfv|)p#CV#(W``21lXP!A=oYw{f&62!aI!os=`Bm~Mx6 zjGu6oagIoNEZP%{8g`C_xe{>io+b6}WtENk$Pq_ZY}wp_GHhW8LZtbF&3qY`vdVrU zK6!XV{+`fo`dC5;hKAxpZ#csL^utz0>kaO0SqZvhphm^R zzX1hGUfX~DNSZFt6c1~5{>HXX5wXfHZvqe7E}x$O?Ah*&pm|$IIuS_O-A_?8jQMhGsdy8h&Tg)kY_3<+fS8TcbiSpP)2tvGhRW=qiDW@E#wCTTR zDT#=#J6D4&B}871Xd}y<@W1^-v!nS25B7NjGUjqMPa28XQPrfsa;HzqpQxd>P=rjZ zjjw~f%(cmE!)ac|`2yGr$t-AO&6TJaU=Sep-7Rjb0>=eS9LIo_thyVo@hvrI{YqWN zN2So`_02Yah|3#(O!M)Z5Aw&|A?}iP&rNZFyztykA9$MVVk=SWwxl4N6$jH@mwUwK zFATj5{R}rKzNh$nAJ-Tr7>*jaO)<()qc}{lmf<|ZMe^xNoj1bpDGS%jVV@jslCgas UKQJ6&OW)%{NDzXwwX|9M2k74{ng9R* diff --git a/bin/kernal_mega65.rom b/bin/kernal_mega65.rom index 67a92cbceaaebd3eb53764694f4e9c9ec8652b8a..a1e4bfcf490abc4a6c40174b97c6c44f0541c4cc 100644 GIT binary patch delta 663 zcmXYuUr19?9LMh;H$yP*R$JG|`aPKG6cy<~2&eRt$?rj85E8gcT3GC%hlHNW!f6P? zm9unMk&G?2NVv2fwn2spDFbDX1w}oW4~A2>dyYb-ojZE@o!{a6#aShAElW@OR>QgBwq!0tqMxck@xxKQN2kYW+X zyztGVRAqDfP+f#W3U8T3^h;?J56LOVjKWvRkf*U(D0MnnaNH8(q}F-c-EY>T&lDg` zjmzA?8aM-fGUrtJK-#(T$jfv|)p#CV#(W``21lXP!A=oYw{f&62!aI!os=`Bm~Mx6 zjGu6oagIoNEZP%{8g`C_xe{>io+b6}WtENk$Pq_ZY}wp_GHhW8LZtbF&3qY`vdVrU zK6!XV{+`fo`dC5;hKAxpZ#csL^utz0>kaO0SqZvhphm^R zzX1hGUfX~DNSZFt6c1~5{>HXX5wXfHZvqe7E}x$O?Ah*&pm|$IIuS_O-A_?8jQMhGsdy8h&Tg)kY_3<+fS8TcbiSpP)2tvGhRW=qiDW@E#wCTTR zDT#=#J6D4&B}871Xd}y<@W1^-v!nS25B7NjGUjqMPa28XQPrfsa;HzqpQxd>P=rjZ zjjw~f%(cmE!)ac|`2yGr$t-AO&6TJaU=Sep-7Rjb0>=eS9LIo_thyVo@hvrI{YqWN zN2So`_02Yah|3#(O!M)Z5Aw&|A?}iP&rNZFyztykA9$MVVk=SWwxl4N6$jH@mwUwK zFATj5{R}rKzNh$nAJ-Tr7>*jaO)<()qc}{lmf<|ZMe^xNoj1bpDGS%jVV@jslCgas UKQJ6&OW)%{NDzXwwX|9M2k74{ng9R* diff --git a/bin/kernal_ultimate64.rom b/bin/kernal_ultimate64.rom index 67a92cbceaaebd3eb53764694f4e9c9ec8652b8a..a1e4bfcf490abc4a6c40174b97c6c44f0541c4cc 100644 GIT binary patch delta 663 zcmXYuUr19?9LMh;H$yP*R$JG|`aPKG6cy<~2&eRt$?rj85E8gcT3GC%hlHNW!f6P? zm9unMk&G?2NVv2fwn2spDFbDX1w}oW4~A2>dyYb-ojZE@o!{a6#aShAElW@OR>QgBwq!0tqMxck@xxKQN2kYW+X zyztGVRAqDfP+f#W3U8T3^h;?J56LOVjKWvRkf*U(D0MnnaNH8(q}F-c-EY>T&lDg` zjmzA?8aM-fGUrtJK-#(T$jfv|)p#CV#(W``21lXP!A=oYw{f&62!aI!os=`Bm~Mx6 zjGu6oagIoNEZP%{8g`C_xe{>io+b6}WtENk$Pq_ZY}wp_GHhW8LZtbF&3qY`vdVrU zK6!XV{+`fo`dC5;hKAxpZ#csL^utz0>kaO0SqZvhphm^R zzX1hGUfX~DNSZFt6c1~5{>HXX5wXfHZvqe7E}x$O?Ah*&pm|$IIuS_O-A_?8jQMhGsdy8h&Tg)kY_3<+fS8TcbiSpP)2tvGhRW=qiDW@E#wCTTR zDT#=#J6D4&B}871Xd}y<@W1^-v!nS25B7NjGUjqMPa28XQPrfsa;HzqpQxd>P=rjZ zjjw~f%(cmE!)ac|`2yGr$t-AO&6TJaU=Sep-7Rjb0>=eS9LIo_thyVo@hvrI{YqWN zN2So`_02Yah|3#(O!M)Z5Aw&|A?}iP&rNZFyztykA9$MVVk=SWwxl4N6$jH@mwUwK zFATj5{R}rKzNh$nAJ-Tr7>*jaO)<()qc}{lmf<|ZMe^xNoj1bpDGS%jVV@jslCgas UKQJ6&OW)%{NDzXwwX|9M2k74{ng9R* diff --git a/c64/kernal/iec/iec_tx_byte.s b/c64/kernal/iec/iec_tx_byte.s index 6a978848..5f24b6c7 100644 --- a/c64/kernal/iec/iec_tx_byte.s +++ b/c64/kernal/iec/iec_tx_byte.s @@ -32,6 +32,8 @@ iec_tx_common: ;; Wait till all receivers are ready, they should all release DATA jsr iec_wait_for_data_release + bcc + + ;; At this point a delay 256 usec or more is considered EOI, ;; receiver should now acknowledge it by pulling data for at least 60 usec ;; Keep the implementation as simple as possible: data should be released now From 6114f982ec40e341d2b157f413a69e7724c0d93e Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Wed, 4 Sep 2019 17:05:46 +0200 Subject: [PATCH 2/9] optimized hex byte printing, idea from Forum64 --- c64/basic/printf.s | 21 ++++++++++----------- c64/kernal/printf.s | 21 ++++++++++----------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/c64/basic/printf.s b/c64/basic/printf.s index ceb4337b..1769660a 100644 --- a/c64/basic/printf.s +++ b/c64/basic/printf.s @@ -139,20 +139,19 @@ printf_retreat: rts printf_printhexbyte: + ;; Print the hex value in .A as two digits, idea by Haubitze + sed pha lsr lsr lsr lsr - ora #$30 - cmp #$3A - bcc + - adc #6 -* jsr JCHROUT + cmp #$0A + adc #$30 + jsr JCHROUT pla - and #$0f - ora #$30 - cmp #$3A - bcc + - adc #6 -* jmp JCHROUT + and #$0F + cmp #$0A + adc #$30 + cld + jmp JCHROUT diff --git a/c64/kernal/printf.s b/c64/kernal/printf.s index 245e9636..ea9776c8 100644 --- a/c64/kernal/printf.s +++ b/c64/kernal/printf.s @@ -139,20 +139,19 @@ printf_retreat: rts printf_printhexbyte: + ;; Print the hex value in .A as two digits, idea by Haubitze + sed pha lsr lsr lsr lsr - ora #$30 - cmp #$3A - bcc + - adc #6 -* jsr JCHROUT + cmp #$0A + adc #$30 + jsr JCHROUT pla - and #$0f - ora #$30 - cmp #$3A - bcc + - adc #6 -* jmp JCHROUT + and #$0F + cmp #$0A + adc #$30 + cld + jmp JCHROUT From ae23dbae7b41fc8692e15bee30e3a60698fe2e95 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 6 Sep 2019 21:24:46 +0200 Subject: [PATCH 3/9] fixed potentially illegal branches --- bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_mega65.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_mega65.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes c64/kernal/f34a.open.s | 4 +++- c64/kernal/iec/iec_tx_byte.s | 3 ++- 8 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index 51ee29800f73cba8b8b48bbf0f181fade29bb85b..71a7c830c8541bd840c0533b5aff008e0eefb3c0 100644 GIT binary patch delta 729 zcmZp0XmDUoUC+0Xc_9$x@_MT34D zz2PEOETW*d`7yf? zljsi*FCaL{m1&@G>3@bMKZtc>vH+L7!L(I#nHW1x34G4*v0T;B(ZO|~e!~5X1?ng3 zCy071Vv*R(z*xC%)m#Rsn)u1_Tyl(Qlk2$RCUXjC$YpKZz+{mCj;b|Gy$p;e6xJ}c z+O1_^Y_;{dw`#Hsw~Xk%jf)r*&i~)=`y}rNfd>H-SQm-;?49h(?IjO%b5$$*GWNX; zOeYmCFu%C)t&Ls5X@kPGRU4QU{5MSA#=YATXu*kurP{5wOLbc97TGRf1X^&C0h~aV zPBdWld9guZ&KiaKjXrg27BB4T@@{V6V`h{V z-LTZ$;;HVcr4~>16nIyyQ~-v^A|-{%%Y67I&*RVLP!Qb!OneGXlfwn uG=bU2Xq|%IGjJ%V%1wBNaHo)8jl-|G%41S=iH)jaW;G6tFkPQIum2Ce2 delta 708 zcmZp0XmDUoT`#hcc_9jgHRMuQ<6 z1K}bkHon~elCNHls;YEN2vB?qSnl*jKPZi=hA3V=+$y4!Q(ZOt>5U4{|10dC9Lo~K zXtH?&%ULGIj>&cG&PuyCw(U|_xp4!Zg2~3Eq92%j^w%vFY2CGwp>-!nSVX~O^J8`) zCTR~ZAmB7OX*GcdXK84J`; z)=v=iSi~Z+mw~Zz%c{8yP&KKOBe~=lb0$}C#ZC4XaF{H^EhBnl<01xy^Zz&eKFRw* z;6cCy)!aqqS) z*tp?D!cy&4+od|Kc8hEmFe`V|2TLa!F#EjQpfG2RLhDAKx-|=!fpQ)lKw?#f zg7D;3JX;tGCdcy{1Ifv}Zy1F)H}EktN=I*4YHsmVchyphr+Ny)t5zxieZ5FYVe&E` zk;(J;vnOBU(g14s&n3+zxIrO$12DZQbW9c$u;Wr_S~P*#$7r2`$>f;=*^I)ISp_{r XJ2t@F29(~w4Ge9d>o+F}&fo(8KcQ#d diff --git a/bin/basic_mega65.rom b/bin/basic_mega65.rom index 84c5459392b97956c0e361a839808e34093eedb6..17939d8975cd6e6173e328d74c890ccfe0f10cf0 100644 GIT binary patch delta 948 zcmb_bUr1A76u*Bq@7&+3bFoVDu#{O#8KkK};hRG)^yfhz%4##|hL7q)K}^Fddr6ib zdl3Y^@|j!vb9Y5TL5L#gO48`5haz7rd$1M@Ef=nDCXuhwcRoH2=R3c1&Ub$28*CkH zWgp^Pnw?_k6@-~Kx)yCPjkF&fXB&fG(-C#QoL0SmEo17d-Ftar$p4gJ?sY2 z4=BNd0{;_^i>UCa021obUAEg*?8vf0O$t|N241hQ!b$W@hmVXUa5(#%_(d)7rXcXs zKB9}UWuXlX>35E9E4Zn7tuBU}*XltRj{2!jNU*3i@K)as2SLlcgDNd&v{T6SkuE7IEe(?}PXRLx-06oG5tXp-{;9G#LIM zPP(;V*x{3P&LxVzgX0s_o=*qrFdw74<_648`tV8`#u9Kr75WpCEW{aKh#WBybZExn zqO(Y|yer8koi~6%kF6eVD<$NUu!Y`RU7SyWyeurB65D{Cbhg-j(mcY!t(bguX&jB( z`kNXQnVSzpI+yvM(4de#$;y;-J}}T339N_sO)U0YlSC|L7?Q%LeDq^K|4pbyEqn|4 z4}E;ls3@?lkdWX;zxeJNTMC_G5{`gsa#;J Osky20>lUPx8-4@FgT8$L delta 889 zcmb_aUr19?7{BLUx4T{M+?{UWvhrgE{h1p^_-|17*08Hc5WN^REnGxIP!9^F23JPD ztWJR>g5Egh*5>^q6%8avg62!2554r@i`7f9Fc(8~9m^tLrSrkzJKy>JzVDph_w_gT zH*@z$!QjSOw1^3N5(V)WwhndU{ajt&sxe}2w(T*>JQuSq;PPWEfWowZ38os(k_hiI8EZYS&BVwP^xqu&82as=i4hhGDZX&wZZH5AqN&U`p3H z2pNQbW6N<6!C!@qs&ETk_S$SH&R(|CUqlZ(|C}%qt3{j|Wl?NST8YZ_xJIlLpQc8c ztw0BE7x$sA>1$#o@-7-MoQ5-|+?yWbAjO7bbW27-z+(;{%Hvtb2P@JlFMth`GC#kr z$w-5B{JzY`x9PB^%CGJ_Z&pw(HwCA1QPsPXYRAkNjyZ2gAzkI4bv`^hClw&1LkNq~ zUZG9@7$Fhqn|uTxlbYzHUzPfV=Q=P3r9uGbr7oLCBc@Hq)RW~H2$VJN~OXT+~IJ3q1AEZ-plP<+WpBylVUpY={loPaldMRxZ)snXH5I$8d Ovu$lMj8t$Uc zPk~7fL~)a1O)P{TGB-JtYD>n{V_R^NP{2v)L@CNT|Lh!_-9_HBKeW%^ezaG0(+7^* z1Fpl4?c}|hecejCR{N6wceUJM@Vy7CI2*V^^ac&Q6-fq*^2Lc&R#}GUjD|pGZlo(2 z=j-l>xx6HpFZ=Ka=#6jkVKMSMJ;PU1nTx}_UjEc@|MU?xWjub*TNH`)M*EpJrajBD zl-H%|m%JToma37o6F9mekXvsVB-;;43VtiY(4$PK>A7w-yW4Sdl| zJrRhRG(LM64Mrnv<_OU0(XFQ1)xKV?4mn4R7G4U@jPsi3O}Qqo2x1f3(nkANMTQK8 z4<41^8pRjESJT{JE$5y#lkOQa*qlAmVh_JnEmkmcmbp puD~6qDj65*pd-_6@K=t9(~%7QTN0;fkawRK-IxzoLf8!-*am0A delta 708 zcmZp0XmDU=T(7o~c_9-M!^X+Wm}&%9Zd_{1YIlLz$9(kyhDEjtO_Pn8RqK^D-bI6H z8JLY0Ftj>j;gA3O&U;q8CdS_#snyhs)i_DJ=`jylv7QUaMEf5Qzo0jrT-b4{4m~RE-rb4IjiO}F?O61_?+QmzpA67gX=*3g!>r_ z)KAt=5cOEZBC(f&v2x3*xeQP>sgonQ4T3Qum}+bEs8VX3*rQ{7cdEuQKr2(MbH0QB@CC56e$ zeAFiU@SmT2jY|Wl{y&#Am+}UM+zr6wrZ8)=vVa|zLeruN%sxiz6x=4S7RUygCNAh9 XI%@;WX+Y@>+`zyFI(~DBU>hF*ujFzt diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index a1e4bfcf490abc4a6c40174b97c6c44f0541c4cc..8085094a01e47af69f3c6bfcf392d2a3eddaae88 100644 GIT binary patch delta 1071 zcmY+Ce`s4(6vtok(rhinzO+gAy104%{d~_I>mTdSTxoEfr3=!ABIBtVlqmVAq1zVDt~9*tXkDjMV9@zr^)$qbFioLI zv!SM}Z0BpyHEQd47&*zG)uz`&aMy|kn#JxO-nEPmO*e$ecynN{+x(-TYVdT?STTQE zIA>pV6`qA)5w^F;x6NH%x2bB;YwEm9<26_-^K*RXJ>@x@PQpt26JeHd!6413xnVnm z$cPf;g@oekuNMrOSr&y(mRZb=*!5WzUo)p7Gm+h+&{gFyaGj;x9IjhwUMoC+_A2a9 zNHKx=r*hD>L!*8@9i59_Gtw$K;@R&rRtk>Zc}a+ga4At$b6GNfHGGQp$)r>VB8B%G_7Y46ok?Ow{79fc8^kYmyqOjs~! z!ITB#)+;e7Dd9yj)Y98_s^&+mNublr^PETYcoI&NWQ%H>Cb^b#!Je9gpOraKBV3j? z0$U+T06XqCS;RNF*rFI$VlX^Pip8>u~zVq%sz|ZE-JRbkqiYD?t^i?#$@h<{-*rVT^$i){m z{fmjO;$Lc<2=ivL>5}qD{1Ms~QQ6jRE#K)4CEHVe?XqsyuG$V}@3(b3<&I>T?A`Z+ zeTZGPo!J$s&v7LCLdP-Np;Qe!8HO0%ruaF<$xZx*;l~W$uHibxB1MDZAjLfluP~e@ m`KR`E>I~1bm|u={%dw!0M>jFYFv^lYrzB01`sm@xo$}w^HSu`> delta 1117 zcmY+Ce`s4(6vtoQOHw-tN!lfSUEDlEX_HzMm;+rO*gv91P;gse zpjG5KbsKGIU4nzKzXn?L4^yPD?B&P16_q~k4J*vY=$3Z+9=w3MvGgQ>W_?;>xwW@2|Wl!hnk zXs-)`wo$SUW(2M~$W(`9#bHY9Rqz5i?LO&dVkD>-+5*=rF@WTTdu;TG4&Akwgtc0$ z-h`W#Fl{IWSIk~eba7CTl{-muVG7O}F)1ue!;A^DCPYnm-+U=7Bm}%jPP7er&oulv z-VlIMdiFk(M__^^+GIiMZFBoUZNAj9H7|$MPZb$b^{sh~HrQQ(-?&?DSy4%3 zWoDIGW=^!_z`rF4KdXSfqAf#?tnBw$CduZ0AFS)l?sn~RUKiDs|3$0NUx9TZdwPa> zXO8fJ_EW({S#oqrx-}G*r4T;13lo$Lya}&$L``9&oU~rEPH+BckT*O79pfAdlm6f_ zz_-bFp2s|EtG5RG6;{bi?EM<=)W|=cVN0DH^Sl;Z^ec0!sHm67innX&uD91N9Z59EfrCGb^81ZyiD%{d~_I>mTdSTxoEfr3=!ABIBtVlqmVAq1zVDt~9*tXkDjMV9@zr^)$qbFioLI zv!SM}Z0BpyHEQd47&*zG)uz`&aMy|kn#JxO-nEPmO*e$ecynN{+x(-TYVdT?STTQE zIA>pV6`qA)5w^F;x6NH%x2bB;YwEm9<26_-^K*RXJ>@x@PQpt26JeHd!6413xnVnm z$cPf;g@oekuNMrOSr&y(mRZb=*!5WzUo)p7Gm+h+&{gFyaGj;x9IjhwUMoC+_A2a9 zNHKx=r*hD>L!*8@9i59_Gtw$K;@R&rRtk>Zc}a+ga4At$b6GNfHGGQp$)r>VB8B%G_7Y46ok?Ow{79fc8^kYmyqOjs~! z!ITB#)+;e7Dd9yj)Y98_s^&+mNublr^PETYcoI&NWQ%H>Cb^b#!Je9gpOraKBV3j? z0$U+T06XqCS;RNF*rFI$VlX^Pip8>u~zVq%sz|ZE-JRbkqiYD?t^i?#$@h<{-*rVT^$i){m z{fmjO;$Lc<2=ivL>5}qD{1Ms~QQ6jRE#K)4CEHVe?XqsyuG$V}@3(b3<&I>T?A`Z+ zeTZGPo!J$s&v7LCLdP-Np;Qe!8HO0%ruaF<$xZx*;l~W$uHibxB1MDZAjLfluP~e@ m`KR`E>I~1bm|u={%dw!0M>jFYFv^lYrzB01`sm@xo$}w^HSu`> delta 1117 zcmY+Ce`s4(6vtoQOHw-tN!lfSUEDlEX_HzMm;+rO*gv91P;gse zpjG5KbsKGIU4nzKzXn?L4^yPD?B&P16_q~k4J*vY=$3Z+9=w3MvGgQ>W_?;>xwW@2|Wl!hnk zXs-)`wo$SUW(2M~$W(`9#bHY9Rqz5i?LO&dVkD>-+5*=rF@WTTdu;TG4&Akwgtc0$ z-h`W#Fl{IWSIk~eba7CTl{-muVG7O}F)1ue!;A^DCPYnm-+U=7Bm}%jPP7er&oulv z-VlIMdiFk(M__^^+GIiMZFBoUZNAj9H7|$MPZb$b^{sh~HrQQ(-?&?DSy4%3 zWoDIGW=^!_z`rF4KdXSfqAf#?tnBw$CduZ0AFS)l?sn~RUKiDs|3$0NUx9TZdwPa> zXO8fJ_EW({S#oqrx-}G*r4T;13lo$Lya}&$L``9&oU~rEPH+BckT*O79pfAdlm6f_ zz_-bFp2s|EtG5RG6;{bi?EM<=)W|=cVN0DH^Sl;Z^ec0!sHm67innX&uD91N9Z59EfrCGb^81ZyiD%{d~_I>mTdSTxoEfr3=!ABIBtVlqmVAq1zVDt~9*tXkDjMV9@zr^)$qbFioLI zv!SM}Z0BpyHEQd47&*zG)uz`&aMy|kn#JxO-nEPmO*e$ecynN{+x(-TYVdT?STTQE zIA>pV6`qA)5w^F;x6NH%x2bB;YwEm9<26_-^K*RXJ>@x@PQpt26JeHd!6413xnVnm z$cPf;g@oekuNMrOSr&y(mRZb=*!5WzUo)p7Gm+h+&{gFyaGj;x9IjhwUMoC+_A2a9 zNHKx=r*hD>L!*8@9i59_Gtw$K;@R&rRtk>Zc}a+ga4At$b6GNfHGGQp$)r>VB8B%G_7Y46ok?Ow{79fc8^kYmyqOjs~! z!ITB#)+;e7Dd9yj)Y98_s^&+mNublr^PETYcoI&NWQ%H>Cb^b#!Je9gpOraKBV3j? z0$U+T06XqCS;RNF*rFI$VlX^Pip8>u~zVq%sz|ZE-JRbkqiYD?t^i?#$@h<{-*rVT^$i){m z{fmjO;$Lc<2=ivL>5}qD{1Ms~QQ6jRE#K)4CEHVe?XqsyuG$V}@3(b3<&I>T?A`Z+ zeTZGPo!J$s&v7LCLdP-Np;Qe!8HO0%ruaF<$xZx*;l~W$uHibxB1MDZAjLfluP~e@ m`KR`E>I~1bm|u={%dw!0M>jFYFv^lYrzB01`sm@xo$}w^HSu`> delta 1117 zcmY+Ce`s4(6vtoQOHw-tN!lfSUEDlEX_HzMm;+rO*gv91P;gse zpjG5KbsKGIU4nzKzXn?L4^yPD?B&P16_q~k4J*vY=$3Z+9=w3MvGgQ>W_?;>xwW@2|Wl!hnk zXs-)`wo$SUW(2M~$W(`9#bHY9Rqz5i?LO&dVkD>-+5*=rF@WTTdu;TG4&Akwgtc0$ z-h`W#Fl{IWSIk~eba7CTl{-muVG7O}F)1ue!;A^DCPYnm-+U=7Bm}%jPP7er&oulv z-VlIMdiFk(M__^^+GIiMZFBoUZNAj9H7|$MPZb$b^{sh~HrQQ(-?&?DSy4%3 zWoDIGW=^!_z`rF4KdXSfqAf#?tnBw$CduZ0AFS)l?sn~RUKiDs|3$0NUx9TZdwPa> zXO8fJ_EW({S#oqrx-}G*r4T;13lo$Lya}&$L``9&oU~rEPH+BckT*O79pfAdlm6f_ zz_-bFp2s|EtG5RG6;{bi?EM<=)W|=cVN0DH^Sl;Z^ec0!sHm67innX&uD91N9Z59EfrCGb^81ZyiD Date: Sat, 7 Sep 2019 12:35:21 +0200 Subject: [PATCH 4/9] adapted to Kick Assembler, some documentation update --- .gitignore | 4 +- .gitmodules | 3 - Makefile | 41 +- Ophis | 1 - README.md | 3 +- STATUS.md | 12 +- assembler/README.TXT | 1 + c64/aliases/,aliases_error_codes.s | 116 ++-- c64/aliases/,aliases_hardware.s | 248 ++++----- c64/aliases/,aliases_ram_lowmem.s | 308 ++++++++--- c64/aliases/,aliases_rom_basic.s | 7 +- c64/aliases/,aliases_rom_cart.s | 8 +- c64/aliases/,aliases_rom_kernal.s | 80 +-- c64/basic/,aliases.s | 230 ++++---- c64/basic/,target_generic/,hooks_generic.s | 9 +- c64/basic/,target_mega65/,hooks_mega65.s | 40 +- .../,target_ultimate64/,hooks_ultimate64.s | 11 +- c64/basic/a000.cold_start_vector.s | 5 +- c64/basic/a002.warm_start_vector.s | 3 +- c64/basic/a004.identifier.s | 10 +- c64/basic/ab1e.print_string.s | 13 +- c64/basic/basic_cold_start.s | 49 +- c64/basic/basic_delete_line.s | 53 +- c64/basic/basic_do_error.s | 29 +- c64/basic/basic_execute_line.s | 157 +++--- c64/basic/basic_find_line.s | 26 +- c64/basic/basic_find_next_line.s | 4 +- c64/basic/basic_insert_line.s | 51 +- c64/basic/basic_main_loop.s | 101 ++-- c64/basic/basic_parse_line_number.s | 16 +- c64/basic/basic_shift_mem_down.s | 104 ++-- c64/basic/basic_shift_mem_up.s | 122 ++--- c64/basic/basic_warm_start.s | 8 +- c64/basic/c000.skip_gap.s | 7 +- c64/basic/cmd_break.s | 25 +- c64/basic/cmd_list.s | 52 +- c64/basic/cmd_load.s | 132 ++--- c64/basic/cmd_new.s | 44 +- c64/basic/cmd_rem.s | 2 +- c64/basic/cmd_run.s | 14 +- c64/basic/cmd_sys.s | 16 +- c64/basic/cmd_unimplemented.s | 18 +- c64/basic/do_basic_error.s | 109 ++-- c64/basic/fac1_mul.s | 52 +- c64/basic/injest_comma.s | 11 +- c64/basic/injest_number.s | 101 ++-- c64/basic/pack_word.s | 175 +++--- c64/basic/peek_pointer_null_check.s | 8 +- c64/basic/print_integer.s | 61 +-- c64/basic/print_packed_message.s | 133 ++--- c64/basic/printf.s | 76 +-- c64/basic/ready_message.s | 4 +- c64/basic/select_device.s | 20 +- c64/basic/tokenise_line.s | 200 +++---- c64/basic/under_rom_routines.s | 55 +- c64/basic/wedge_dos.s | 178 +++--- c64/kernal/,aliases.s | 138 ++--- c64/kernal/,target_generic/,hooks_generic.s | 6 +- c64/kernal/,target_mega65/,hooks_mega65.s | 6 +- .../,target_ultimate64/,aliases_ultimate64.s | 98 ++-- .../,target_ultimate64/,hooks_ultimate64.s | 12 +- .../,target_ultimate64/u64_load.s.disabled | 93 ++-- c64/kernal/acptr.s | 19 +- c64/kernal/blink_cursor.s | 40 +- c64/kernal/cartridge_check.s | 2 +- c64/kernal/chkinout_real.s | 74 +-- c64/kernal/chrin_real.s | 120 ++--- c64/kernal/chrout_real.s | 506 +++++++++--------- c64/kernal/cint_real.s | 80 +-- c64/kernal/ciout.s | 28 +- c64/kernal/clall_real.s | 40 +- c64/kernal/close_load.s | 14 +- c64/kernal/clrchn_real.s | 42 +- c64/kernal/e544.clear_screen.s | 46 +- c64/kernal/e5a0.setup_vicii.s | 14 +- c64/kernal/errors.s | 10 +- c64/kernal/f13e.getin.s | 28 +- c64/kernal/f157.chrin.jmp.s | 6 +- c64/kernal/f1ca.chrout.jmp.s | 6 +- c64/kernal/f20e.chkin.jmp.s | 6 +- c64/kernal/f250.ckout.jmp.s | 6 +- c64/kernal/f291.close.s | 54 +- c64/kernal/f32f.clall.jmp.s | 6 +- c64/kernal/f333.clrchn.jmp.s | 6 +- c64/kernal/f34a.open.s | 64 +-- c64/kernal/f4a5.load.s | 184 +++---- c64/kernal/f5ed.save.s | 20 +- c64/kernal/f6ed.stop.s | 30 +- c64/kernal/fd15.vector.s | 66 ++- c64/kernal/fda3.ioinit.s | 68 +-- c64/kernal/ff5b.cint.jmp.s | 6 +- c64/kernal/ff80.kernal_revision.s | 88 ++- c64/kernal/fffa.s | 4 +- c64/kernal/fffc.s | 4 +- c64/kernal/fffe.s | 6 +- c64/kernal/findfls.s | 14 +- c64/kernal/home_cursor.s | 4 +- c64/kernal/iec/iec_check_devnum.s | 26 +- c64/kernal/iec/iec_cmd_close.s | 14 +- c64/kernal/iec/iec_cmd_open.s | 44 +- .../iec/iec_pull_atn_clk_release_data.s | 12 +- c64/kernal/iec/iec_pull_clk_release_data.s | 10 +- .../iec/iec_pull_clk_release_data_oneshot.s | 4 +- .../iec/iec_pull_data_release_atn_clk.s | 12 +- c64/kernal/iec/iec_release_atn.s | 2 +- c64/kernal/iec/iec_release_atn_clk_data.s | 12 +- c64/kernal/iec/iec_release_clk_data.s | 10 +- c64/kernal/iec/iec_release_clk_pull_data.s | 10 +- c64/kernal/iec/iec_return.s | 30 +- c64/kernal/iec/iec_rx_byte.s | 140 ++--- c64/kernal/iec/iec_set_idle.s | 4 +- c64/kernal/iec/iec_turnaround_to_listen.s | 30 +- c64/kernal/iec/iec_turnaround_to_talk.s | 16 +- c64/kernal/iec/iec_tx_byte.s | 80 +-- c64/kernal/iec/iec_tx_command.s | 38 +- c64/kernal/iec/iec_tx_command_finalize.s | 10 +- c64/kernal/iec/iec_tx_flush.s | 14 +- c64/kernal/iec/iec_wait1ms.s | 22 +- c64/kernal/iec/iec_wait20us.s | 30 +- c64/kernal/iec/iec_wait60us.s | 30 +- c64/kernal/iec/iec_wait_for_data_pull.s | 4 +- c64/kernal/iec/iec_wait_for_data_release.s | 4 +- .../interrupts/ea31.default_irq_handler.s | 7 +- .../ea7e.ack_cia1_return_from_interrupt.s | 14 +- .../interrupts/ea81.return_from_interrupt.s | 22 +- .../interrupts/fe47.default_nmi_handler.s | 25 +- .../interrupts/fe66.default_brk_handler.s | 6 +- c64/kernal/interrupts/irq_handler.s | 32 +- c64/kernal/interrupts/nmi_handler.s | 10 +- c64/kernal/jumptable/ff81.jcint.s | 7 +- c64/kernal/jumptable/ff84.jioinit.s | 7 +- c64/kernal/jumptable/ff87.jramtas.s | 7 +- c64/kernal/jumptable/ff8a.jrestor.s | 7 +- c64/kernal/jumptable/ff8d.jvector.s | 7 +- c64/kernal/jumptable/ff90.jsetmsg.s | 7 +- c64/kernal/jumptable/ff93.jsecond.s | 7 +- c64/kernal/jumptable/ff96.jtksa.s | 7 +- c64/kernal/jumptable/ff99.jmemtop.s | 7 +- c64/kernal/jumptable/ff9c.jmembot.s | 7 +- c64/kernal/jumptable/ff9f.jscnkey.s | 5 +- c64/kernal/jumptable/ffa2.jsettmo.s | 7 +- c64/kernal/jumptable/ffa5.jacptr.s | 7 +- c64/kernal/jumptable/ffa8.jciout.s | 7 +- c64/kernal/jumptable/ffab.juntlk.s | 7 +- c64/kernal/jumptable/ffae.junlsn.s | 7 +- c64/kernal/jumptable/ffb1.jlisten.s | 7 +- c64/kernal/jumptable/ffb4.jtalk.s | 7 +- c64/kernal/jumptable/ffb7.jreadst.s | 7 +- c64/kernal/jumptable/ffba.jsetfls.s | 7 +- c64/kernal/jumptable/ffbd.jsetnam.s | 7 +- c64/kernal/jumptable/ffc0.jopen.s | 7 +- c64/kernal/jumptable/ffc3.jclose.s | 7 +- c64/kernal/jumptable/ffc6.jchkin.s | 7 +- c64/kernal/jumptable/ffc9.jckout.s | 7 +- c64/kernal/jumptable/ffcc.jclrchn.s | 7 +- c64/kernal/jumptable/ffcf.jchrin.s | 7 +- c64/kernal/jumptable/ffd2.jchrout.s | 7 +- c64/kernal/jumptable/ffd5.jload.s | 7 +- c64/kernal/jumptable/ffd8.jsave.s | 7 +- c64/kernal/jumptable/ffdb.jsettim.s | 7 +- c64/kernal/jumptable/ffde.jrdtim.s | 7 +- c64/kernal/jumptable/ffe1.jstop.s | 7 +- c64/kernal/jumptable/ffe4.jgetin.s | 7 +- c64/kernal/jumptable/ffe7.jclall.s | 7 +- c64/kernal/jumptable/ffea.judtim.s | 4 +- c64/kernal/jumptable/ffed.jscreen.s | 6 +- c64/kernal/jumptable/fff0.jplot.s | 10 +- c64/kernal/jumptable/fff3.jiobase.s | 20 +- c64/kernal/keyboard_matrix.s | 61 ++- c64/kernal/listen.s | 32 +- c64/kernal/lvs_helpers.s | 328 ++++++------ c64/kernal/membot.s | 18 +- c64/kernal/memtop.s | 18 +- c64/kernal/plot.s | 23 +- c64/kernal/printf.s | 76 +-- c64/kernal/ramtas.s | 74 +-- c64/kernal/rdtim.s | 36 +- c64/kernal/readst.s | 34 +- c64/kernal/reset_entry.s | 44 +- c64/kernal/scnkey.s | 429 ++++++++------- c64/kernal/screen.s | 26 +- c64/kernal/second.s | 30 +- .../set_pointer_to_current_screen_line.s | 20 +- c64/kernal/setfls.s | 22 +- c64/kernal/setmsg.s | 18 +- c64/kernal/setnam.s | 22 +- c64/kernal/settim.s | 30 +- c64/kernal/settmo.s | 18 +- c64/kernal/talk.s | 34 +- c64/kernal/tksa.s | 30 +- c64/kernal/udtim.s | 44 +- c64/kernal/under_rom_routines.s | 28 +- c64/kernal/unlsn.s | 26 +- c64/kernal/untlk.s | 40 +- c64/kernal/vector_defaults.s | 44 +- c64/program_traces/README.md | 2 +- src/compress_text.c | 6 +- src/preprocess.c | 107 ++-- 198 files changed, 4181 insertions(+), 3976 deletions(-) delete mode 160000 Ophis create mode 100644 assembler/README.TXT diff --git a/.gitignore b/.gitignore index 1d25926a..ffd89384 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,9 @@ # Compilation related files temp.s -temp.map +temp.sym -ophis.bin +assembler/KickAss* build/* # Input to the similarity tool - copyrighted material, we can't check it in! diff --git a/.gitmodules b/.gitmodules index 5d73f4e5..e69de29b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "Ophis"] - path = Ophis - url = https://github.com/gardners/Ophis.git diff --git a/Makefile b/Makefile index a6a214d8..5080e7ed 100644 --- a/Makefile +++ b/Makefile @@ -33,15 +33,10 @@ GIT_COMMIT:= $(shell git log -1 --pretty='%h' | tr '[:lower:]' '[:upper:]') all: build/chargen build/newkern_generic build/newbasic_generic build/newc65 build/newkern_ultimate64 build/newbasic_ultimate64 -Ophis: - git submodule init - git submodule update - clean: @rm -rf build @rm -f temp.s - @rm -f temp.map - @rm -f ophis.bin + @rm -f temp.sym updatebin: build/chargen build/newbasic_generic build/newkern_generic build/newbasic_mega65 build/newkern_mega65 build/newbasic_ultimate64 build/newkern_ultimate64 cp build/chargen bin/chargen.rom @@ -81,23 +76,23 @@ build/chargen: $(TOOL_PNGPREPARE) assets/8x8font.png # Dependencies -build/basic_generic/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_generic) build/basic/packed_messages.s -build/kernal_generic/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_generic) -build/newrom_generic: build/basic_generic/OUT.BIN build/kernal_generic/OUT.BIN -build/newkern_generic: build/newrom_generic Makefile -build/newbasic_generic: build/newrom_generic Makefile +build/basic_generic/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_generic) build/basic/packed_messages.s +build/kernal_generic/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_generic) +build/newrom_generic: build/basic_generic/OUT.BIN build/kernal_generic/OUT.BIN +build/newkern_generic: build/newrom_generic Makefile +build/newbasic_generic: build/newrom_generic Makefile -build/basic_mega65/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_mega65) build/basic/packed_messages.s -build/kernal_mega65/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_mega65) -build/newrom_mega65: build/basic_mega65/OUT.BIN build/kernal_mega65/OUT.BIN -build/newkern_mega65: build/newrom_mega65 Makefile -build/newbasic_mega65: build/newrom_mega65 Makefile +build/basic_mega65/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_mega65) build/basic/packed_messages.s +build/kernal_mega65/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_mega65) +build/newrom_mega65: build/basic_mega65/OUT.BIN build/kernal_mega65/OUT.BIN +build/newkern_mega65: build/newrom_mega65 Makefile +build/newbasic_mega65: build/newrom_mega65 Makefile -build/basic_ultimate64/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_ultimate64) build/basic/packed_messages.s -build/kernal_ultimate64/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_ultimate64) -build/newrom_ultimate64: build/basic_ultimate64/OUT.BIN build/kernal_ultimate64/OUT.BIN -build/newkern_ultimate64: build/newrom_ultimate64 Makefile -build/newbasic_ultimate64: build/newrom_ultimate64 Makefile +build/basic_ultimate64/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_ultimate64) build/basic/packed_messages.s +build/kernal_ultimate64/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_ultimate64) +build/newrom_ultimate64: build/basic_ultimate64/OUT.BIN build/kernal_ultimate64/OUT.BIN +build/newkern_ultimate64: build/newrom_ultimate64 Makefile +build/newbasic_ultimate64: build/newrom_ultimate64 Makefile # Rules - BASIC and KERNAL @@ -107,7 +102,7 @@ build/basic/packed_messages.s: $(TOOL_COMPRESS_TEXT) $(TOOL_COMPRESS_TEXT) > build/basic/packed_messages.s .PRECIOUS: build/basic_%/OUT.BIN -build/basic_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_messages.s +build/basic_%/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_messages.s @mkdir -p build/basic_$* @rm -f build/basic_$*/* @for SRC in $(SRC_BASIC_$*); do \ @@ -117,7 +112,7 @@ build/basic_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_me $(TOOL_PREPROCESS) -d build/basic_$* -l a000 -h e4d2 .PRECIOUS: build/kernal_%/OUT.BIN -build/kernal_%/OUT.BIN: Ophis $(TOOLS_LIST) $(SRC_KERNAL_$*) +build/kernal_%/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_$*) @mkdir -p build/kernal_$* @rm -f build/kernal_$*/* @for SRC in $(SRC_KERNAL_$*); do \ diff --git a/Ophis b/Ophis deleted file mode 160000 index 15818e76..00000000 --- a/Ophis +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 15818e7666cc4b05993e0f5724c664671b0c1cae diff --git a/README.md b/README.md index c6e5b236..86dc2978 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # open-roms -A project to create unencumbered open-source ROMs for use on selected retro computers + +A project to create unencumbered open-source ROMs for use on selected retro computers. For the current status check [this document](STATUS.md) # Problem Statement and Motivation diff --git a/STATUS.md b/STATUS.md index 65bf9f8f..3759a299 100644 --- a/STATUS.md +++ b/STATUS.md @@ -38,16 +38,10 @@ The following ROM features are currently missing: Status of the various APIs and variables from the original ROMs -## Page 0 +## Low memory locations (pages 0 - 3) -TODO - - -## Pages 2 & 3 - - -TODO +For the current status of the low memory location implementation andd usage check [this file](c64/aliases/,aliases_ram_lowmem.s). NOTE: available vector to certain routine does not mean that this routine is fully implemented! ## BASIC @@ -107,7 +101,7 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on | `$FFE7` | `CLALL` | DONE | | | `$FFEA` | `UDTIM` | DONE | | | `$FFED` | `SCREEN` | DONE | | -| `$FFF0` | `PLOT` | DONE | | +| `$FFF0` | `PLOT` | PARTIAL | cursor blink not handled | | `$FFF3` | `IOBASE` | DONE | |
diff --git a/assembler/README.TXT b/assembler/README.TXT new file mode 100644 index 00000000..3bc6fa41 --- /dev/null +++ b/assembler/README.TXT @@ -0,0 +1 @@ +Put KickAss.jar and KickAss.cfg into this directory. diff --git a/c64/aliases/,aliases_error_codes.s b/c64/aliases/,aliases_error_codes.s index e27f5373..5af898a1 100644 --- a/c64/aliases/,aliases_error_codes.s +++ b/c64/aliases/,aliases_error_codes.s @@ -1,63 +1,63 @@ - ;; Kernal error codes - returned in the A register - ;; Described in 'Commodore 64 Programmer's Reference Guide', page 306 + // Kernal error codes - returned in the A register + // Described in 'Commodore 64 Programmer's Reference Guide', page 306 - .alias K_ERR_ROUTINE_TERMINATED $00 - .alias K_ERR_TOO_MANY_OPEN_FILES $01 - .alias K_ERR_FILE_ALREADY_OPEN $02 - .alias K_ERR_FILE_NOT_OPEN $03 - .alias K_ERR_FILE_NOT_FOUND $04 - .alias K_ERR_DEVICE_NOT_FOUND $05 - .alias K_ERR_FILE_NOT_INPUT $06 - .alias K_ERR_FILE_NOT_OUTPUT $07 - .alias K_ERR_FILE_NAME_MISSING $08 - .alias K_ERR_ILLEGAL_DEVICE_NUMBER $09 - .alias K_ERR_TOP_MEM_RS232 $F0 + .const K_ERR_ROUTINE_TERMINATED = $00 + .const K_ERR_TOO_MANY_OPEN_FILES = $01 + .const K_ERR_FILE_ALREADY_OPEN = $02 + .const K_ERR_FILE_NOT_OPEN = $03 + .const K_ERR_FILE_NOT_FOUND = $04 + .const K_ERR_DEVICE_NOT_FOUND = $05 + .const K_ERR_FILE_NOT_INPUT = $06 + .const K_ERR_FILE_NOT_OUTPUT = $07 + .const K_ERR_FILE_NAME_MISSING = $08 + .const K_ERR_ILLEGAL_DEVICE_NUMBER = $09 + .const K_ERR_TOP_MEM_RS232 = $F0 - ;; Kernal status codes for READST routine (IOSTATUS) - ;; Described in 'Commodore 64 Programmer's Reference Guide', page 292 + // Kernal status codes for READST routine (IOSTATUS) + // Described in 'Commodore 64 Programmer's Reference Guide', page 292 - ;; For IEC devices - .alias K_STS_TIMEOUT_WRITE $01 - .alias K_STS_TIMEOUT_READ $02 - .alias K_STS_EOI $40 - .alias K_STS_DEVICE_NOT_FOUND $80 - ;; For tape deck - .alias K_STS_SHORT_BLOCK $04 - .alias K_STS_LONG_BLOCK $08 - .alias K_STS_READ_ERROR $10 - .alias K_STS_CHECKSUM_ERROR $20 - .alias K_STS_END_OF_FILE $40 - .alias K_STS_END_OF_TAPE $80 + // For IEC devices + .const K_STS_TIMEOUT_WRITE = $01 + .const K_STS_TIMEOUT_READ = $02 + .const K_STS_EOI = $40 + .const K_STS_DEVICE_NOT_FOUND = $80 + // For tape deck + .const K_STS_SHORT_BLOCK = $04 + .const K_STS_LONG_BLOCK = $08 + .const K_STS_READ_ERROR = $10 + .const K_STS_CHECKSUM_ERROR = $20 + .const K_STS_END_OF_FILE = $40 + .const K_STS_END_OF_TAPE = $80 - ;; BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html - .alias B_ERR_TOO_MANY_FILES $01 - .alias B_ERR_FILE_OPEN $02 - .alias B_ERR_FILE_NOT_OPEN $03 - .alias B_ERR_FILE_NOT_FOUND $04 - .alias B_ERR_DEVICE_NOT_PRESENT $05 - .alias B_ERR_NOT_INPUT_FILE $06 - .alias B_ERR_NOT_OUTPUT_FILE $07 - .alias B_ERR_MISSING_FILENAME $08 - .alias B_ERR_ILLEGAL_DEVICE_NUMBER $09 - .alias B_ERR_NEXT_WITHOUT_FOR $0A - .alias B_ERR_SYNTAX $0B - .alias B_ERR_RETURN_WITHOUT_GOSUB $0C - .alias B_ERR_OUT_OF_DATA $0D - .alias B_ERR_ILLEGAL_QUANTITY $0E - .alias B_ERR_OVERFLOW $0F - .alias B_ERR_OUT_OF_MEMORY $10 - .alias B_ERR_UNDEFD_STATEMENT $11 - .alias B_ERR_BAD_SUBSCRIPT $12 - .alias B_ERR_REDIMD_ARRAY $13 - .alias B_ERR_DIVISION_BY_ZERO $14 - .alias B_ERR_ILLEGAL_DIRECT $15 - .alias B_ERR_TYPE_MISMATCH $16 - .alias B_ERR_STRING_TOO_LONG $17 - .alias B_ERR_FILE_DATA $18 - .alias B_ERR_FORMULA_TOO_COMPLEX $19 - .alias B_ERR_CANT_CONTINUE $1A - .alias B_ERR_UNDEFD_FUNCTION $1B - .alias B_ERR_VERIFY $1C - .alias B_ERR_LOAD $1D - .alias B_ERR_BREAK $1E + // BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html + .const B_ERR_TOO_MANY_FILES = $01 + .const B_ERR_FILE_OPEN = $02 + .const B_ERR_FILE_NOT_OPEN = $03 + .const B_ERR_FILE_NOT_FOUND = $04 + .const B_ERR_DEVICE_NOT_PRESENT = $05 + .const B_ERR_NOT_INPUT_FILE = $06 + .const B_ERR_NOT_OUTPUT_FILE = $07 + .const B_ERR_MISSING_FILENAME = $08 + .const B_ERR_ILLEGAL_DEVICE_NUMBER = $09 + .const B_ERR_NEXT_WITHOUT_FOR = $0A + .const B_ERR_SYNTAX = $0B + .const B_ERR_RETURN_WITHOUT_GOSUB = $0C + .const B_ERR_OUT_OF_DATA = $0D + .const B_ERR_ILLEGAL_QUANTITY = $0E + .const B_ERR_OVERFLOW = $0F + .const B_ERR_OUT_OF_MEMORY = $10 + .const B_ERR_UNDEFD_STATEMENT = $11 + .const B_ERR_BAD_SUBSCRIPT = $12 + .const B_ERR_REDIMD_ARRAY = $13 + .const B_ERR_DIVISION_BY_ZERO = $14 + .const B_ERR_ILLEGAL_DIRECT = $15 + .const B_ERR_TYPE_MISMATCH = $16 + .const B_ERR_STRING_TOO_LONG = $17 + .const B_ERR_FILE_DATA = $18 + .const B_ERR_FORMULA_TOO_COMPLEX = $19 + .const B_ERR_CANT_CONTINUE = $1A + .const B_ERR_UNDEFD_FUNCTION = $1B + .const B_ERR_VERIFY = $1C + .const B_ERR_LOAD = $1D + .const B_ERR_BREAK = $1E diff --git a/c64/aliases/,aliases_hardware.s b/c64/aliases/,aliases_hardware.s index cc57faa3..2eee3541 100644 --- a/c64/aliases/,aliases_hardware.s +++ b/c64/aliases/,aliases_hardware.s @@ -1,148 +1,148 @@ -;; -;; Names of hardware registers - slightly modified names from C64 Programmer's Reference Guide -;; +// +// Names of hardware registers - slightly modified names from C64 Programmer's Reference Guide +// - ;; CPU memory registers + // CPU memory registers - .alias CPU_D6510 $00 - .alias CPU_R6510 $01 + .label CPU_D6510 = $00 + .label CPU_R6510 = $01 - ;; VIC-II registers + // VIC-II registers - .alias VIC_SP0X $D000 - .alias VIC_SP0Y $D001 - .alias VIC_SP1X $D002 - .alias VIC_SP1Y $D003 - .alias VIC_SP2X $D004 - .alias VIC_SP2Y $D005 - .alias VIC_SP3X $D006 - .alias VIC_SP3Y $D007 - .alias VIC_SP4X $D008 - .alias VIC_SP4Y $D009 - .alias VIC_SP5X $D00A - .alias VIC_SP5Y $D00B - .alias VIC_SP6X $D00C - .alias VIC_SP6Y $D00D - .alias VIC_SP7X $D00E - .alias VIC_SP7Y $D00F + .label VIC_SP0X = $D000 + .label VIC_SP0Y = $D001 + .label VIC_SP1X = $D002 + .label VIC_SP1Y = $D003 + .label VIC_SP2X = $D004 + .label VIC_SP2Y = $D005 + .label VIC_SP3X = $D006 + .label VIC_SP3Y = $D007 + .label VIC_SP4X = $D008 + .label VIC_SP4Y = $D009 + .label VIC_SP5X = $D00A + .label VIC_SP5Y = $D00B + .label VIC_SP6X = $D00C + .label VIC_SP6Y = $D00D + .label VIC_SP7X = $D00E + .label VIC_SP7Y = $D00F - .alias VIC_MSIGX $D010 - .alias VIC_SCROLY $D011 - .alias VIC_RASTER $D012 - .alias VIC_LPENX $D013 - .alias VIC_LPENY $D014 - .alias VIC_SPENA $D015 - .alias VIC_SCROLX $D016 - .alias VIC_YXPAND $D017 - .alias VIC_YMCSB $D018 - .alias VIC_IRQ $D019 - .alias VIC_IRQMSK $D01A - .alias VIC_SPBGPR $D01B - .alias VIC_SPMC $D01C - .alias VIC_XXPAND $D01D - .alias VIC_SPSPCL $D01E - .alias VIC_SPBGCL $D01F + .label VIC_MSIGX = $D010 + .label VIC_SCROLY = $D011 + .label VIC_RASTER = $D012 + .label VIC_LPENX = $D013 + .label VIC_LPENY = $D014 + .label VIC_SPENA = $D015 + .label VIC_SCROLX = $D016 + .label VIC_YXPAND = $D017 + .label VIC_YMCSB = $D018 + .label VIC_IRQ = $D019 + .label VIC_IRQMSK = $D01A + .label VIC_SPBGPR = $D01B + .label VIC_SPMC = $D01C + .label VIC_XXPAND = $D01D + .label VIC_SPSPCL = $D01E + .label VIC_SPBGCL = $D01F - .alias VIC_EXTCOL $D020 - .alias VIC_BGCOL0 $D021 - .alias VIC_BGCOL1 $D022 - .alias VIC_BGCOL2 $D023 - .alias VIC_BGCOL3 $D024 - .alias VIC_SPMC0 $D025 - .alias VIC_SPMC1 $D026 - .alias VIC_SP0COL $D027 - .alias VIC_SP1COL $D028 - .alias VIC_SP2COL $D029 - .alias VIC_SP3COL $D02A - .alias VIC_SP4COL $D02B - .alias VIC_SP5COL $D02C - .alias VIC_SP6COL $D02D - .alias VIC_SP7COL $D02E + .label VIC_EXTCOL = $D020 + .label VIC_BGCOL0 = $D021 + .label VIC_BGCOL1 = $D022 + .label VIC_BGCOL2 = $D023 + .label VIC_BGCOL3 = $D024 + .label VIC_SPMC0 = $D025 + .label VIC_SPMC1 = $D026 + .label VIC_SP0COL = $D027 + .label VIC_SP1COL = $D028 + .label VIC_SP2COL = $D029 + .label VIC_SP3COL = $D02A + .label VIC_SP4COL = $D02B + .label VIC_SP5COL = $D02C + .label VIC_SP6COL = $D02D + .label VIC_SP7COL = $D02E - ;; SID registers + // SID registers - .alias SID_FRELO1 $D400 - .alias SID_FREHI1 $D401 - .alias SID_PWLO1 $D402 - .alias SID_PWHI1 $D403 - .alias SID_VCREG1 $D404 - .alias SID_ATDCY1 $D405 - .alias SID_SUREL1 $D406 + .label SID_FRELO1 = $D400 + .label SID_FREHI1 = $D401 + .label SID_PWLO1 = $D402 + .label SID_PWHI1 = $D403 + .label SID_VCREG1 = $D404 + .label SID_ATDCY1 = $D405 + .label SID_SUREL1 = $D406 - .alias SID_FRELO2 $D407 - .alias SID_FREHI2 $D408 - .alias SID_PWLO2 $D409 - .alias SID_PWHI2 $D40A - .alias SID_VCREG2 $D40B - .alias SID_ATDCY2 $D40C - .alias SID_SUREL2 $D40D + .label SID_FRELO2 = $D407 + .label SID_FREHI2 = $D408 + .label SID_PWLO2 = $D409 + .label SID_PWHI2 = $D40A + .label SID_VCREG2 = $D40B + .label SID_ATDCY2 = $D40C + .label SID_SUREL2 = $D40D - .alias SID_FRELO3 $D40E - .alias SID_FREHI3 $D40F - .alias SID_PWLO3 $D410 - .alias SID_PWHI3 $D411 - .alias SID_VCREG3 $D412 - .alias SID_ATDCY3 $D413 - .alias SID_SUREL3 $D414 + .label SID_FRELO3 = $D40E + .label SID_FREHI3 = $D40F + .label SID_PWLO3 = $D410 + .label SID_PWHI3 = $D411 + .label SID_VCREG3 = $D412 + .label SID_ATDCY3 = $D413 + .label SID_SUREL3 = $D414 - .alias SID_CUTLO $D415 - .alias SID_CUTHI $D416 - .alias SID_RESON $D417 - .alias SID_SIGVOL $D418 - .alias SID_POTX $D419 - .alias SID_POTY $D41A - .alias SID_RANDOM $D41B - .alias SID_ENV3 $D41C + .label SID_CUTLO = $D415 + .label SID_CUTHI = $D416 + .label SID_RESON = $D417 + .label SID_SIGVOL = $D418 + .label SID_POTX = $D419 + .label SID_POTY = $D41A + .label SID_RANDOM = $D41B + .label SID_ENV3 = $D41C - ;; CIA #1 registers + // CIA #1 registers - .alias CIA1_PRA $DC00 - .alias CIA1_PRB $DC01 - .alias CIA1_DDRA $DC02 - .alias CIA1_DDRB $DC03 + .label CIA1_PRA = $DC00 + .label CIA1_PRB = $DC01 + .label CIA1_DDRA = $DC02 + .label CIA1_DDRB = $DC03 - .alias CIA1_TIMALO $DC04 - .alias CIA1_TIMAHI $DC05 - .alias CIA1_TIMBLO $DC06 - .alias CIA1_TIMBHI $DC07 + .label CIA1_TIMALO = $DC04 + .label CIA1_TIMAHI = $DC05 + .label CIA1_TIMBLO = $DC06 + .label CIA1_TIMBHI = $DC07 - .alias CIA1_TODTEN $DC08 - .alias CIA1_TODSEC $DC09 - .alias CIA1_TODMIN $DC0A - .alias CIA1_TODHRS $DC0B + .label CIA1_TODTEN = $DC08 + .label CIA1_TODSEC = $DC09 + .label CIA1_TODMIN = $DC0A + .label CIA1_TODHRS = $DC0B - .alias CIA1_SDR $DC0C - .alias CIA1_ICR $DC0D - .alias CIA1_CRA $DC0E - .alias CIA1_CRB $DC0F + .label CIA1_SDR = $DC0C + .label CIA1_ICR = $DC0D + .label CIA1_CRA = $DC0E + .label CIA1_CRB = $DC0F - ;; CIA #2 registers + // CIA #2 registers - .alias CIA2_PRA $DD00 ; VIC bank switching and IEC port - .alias CIA2_PRB $DD01 - .alias CIA2_DDRA $DD02 - .alias CIA2_DDRB $DD03 + .label CIA2_PRA = $DD00 // VIC bank switching and IEC port + .label CIA2_PRB = $DD01 + .label CIA2_DDRA = $DD02 + .label CIA2_DDRB = $DD03 - .alias CIA2_TIMALO $DD04 - .alias CIA2_TIMAHI $DD05 - .alias CIA2_TIMBLO $DD06 - .alias CIA2_TIMBHI $DD07 + .label CIA2_TIMALO = $DD04 + .label CIA2_TIMAHI = $DD05 + .label CIA2_TIMBLO = $DD06 + .label CIA2_TIMBHI = $DD07 - .alias CIA2_TODTEN $DD08 - .alias CIA2_TODSEC $DD09 - .alias CIA2_TODMIN $DD0A - .alias CIA2_TODHRS $DD0B + .label CIA2_TODTEN = $DD08 + .label CIA2_TODSEC = $DD09 + .label CIA2_TODMIN = $DD0A + .label CIA2_TODHRS = $DD0B - .alias CIA2_SDR $DD0C - .alias CIA2_ICR $DD0D - .alias CIA2_CRA $DD0E - .alias CIA2_CRB $DD0F + .label CIA2_SDR = $DD0C + .label CIA2_ICR = $DD0D + .label CIA2_CRA = $DD0E + .label CIA2_CRB = $DD0F - ;; CIA #2 helper bits - IEC bus + // CIA #2 helper bits - IEC bus - .alias BIT_CIA2_PRA_ATN_OUT $08 ; 1 - low (pulled), 0 - high (released) - .alias BIT_CIA2_PRA_CLK_OUT $10 ; 1 - low (pulled), 0 - high (released) - .alias BIT_CIA2_PRA_DAT_OUT $20 ; 1 - low (pulled), 0 - high (released) - .alias BIT_CIA2_PRA_CLK_IN $40 ; 0 - low (pulled), 1 - high (released) - .alias BIT_CIA2_PRA_DAT_IN $80 ; 0 - low (pulled), 1 - high (released) + .const BIT_CIA2_PRA_ATN_OUT = $08 // 1 - low (pulled), 0 - high (released) + .const BIT_CIA2_PRA_CLK_OUT = $10 // 1 - low (pulled), 0 - high (released) + .const BIT_CIA2_PRA_DAT_OUT = $20 // 1 - low (pulled), 0 - high (released) + .const BIT_CIA2_PRA_CLK_IN = $40 // 0 - low (pulled), 1 - high (released) + .const BIT_CIA2_PRA_DAT_IN = $80 // 0 - low (pulled), 1 - high (released) diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index d72deec7..8b116ec7 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -1,98 +1,236 @@ -;; -;; Names of ZP and low memory locations -;; (https://www.c64-wiki.com/wiki/Zeropage) -;; +// +// Names of ZP and low memory locations: +// - Compute's Mapping the Commodore 64 +// - https://www.c64-wiki.com/wiki/Zeropage +// - http://unusedino.de/ec64/technical/project64/memory_maps.html +// - ;; $00-$01 - 6502 CPU registers are here + // $00-$01 - 6502 CPU registers are here - ;; - ;; Page 0 - BASIC area ($02-$8F) - ;; + // + // Page 0 - BASIC area ($02-$8F) + // + + // $02 -- UNUSED -- free for user software + .label ADRAY1 = $03 // $03-$04 -- NOT IMPLEMENTED -- + .label ADRAY2 = $05 // $05-$06 -- NOT IMPLEMENTED -- + .label CHARAC = $07 // [!] our implementation might be different XXX give more details + .label ENDCHR = $08 // [!] our implementation might be different XXX give more details + .label TRMPOS = $09 // -- NOT IMPLEMENTED -- + .label VERCKB = $0A // -- NOT IMPLEMENTED -- + .label COUNT = $0B // [!] our implementation might be different XXX give more details + .label DIMFLG = $0C // [!] our implementation might be different XXX give more details + .label VALTYP = $0D // -- NOT IMPLEMENTED -- + .label INTFLG = $0E // -- NOT IMPLEMENTED -- + .label GARBFL = $0F // [!] our implementation might be different XXX give more details + .label SUBFLG = $10 // -- NOT IMPLEMENTED -- + .label INPFLG = $11 // -- NOT IMPLEMENTED -- + .label TANSGN = $12 // -- NOT IMPLEMENTED -- + .label CHANNL = $13 // -- NOT IMPLEMENTED -- + .label LINNUM = $14 // $14-$15 BASIC line number, [!] also used by DOS Wedge + .label TEMPPT = $16 // -- NOT IMPLEMENTED -- + .label LASTPT = $17 // $17-$18 -- NOT IMPLEMENTED -- + .label TEMPST = $19 // $19-$21 -- NOT IMPLEMENTED -- + .label INDEX = $22 // $22-$25 -- NOT IMPLEMENTED -- temporary variables + .label RESHO = $26 // $26-$2A -- NOT IMPLEMENTED -- + .label TXTTAB = $2B // $2B-$2C start of BASIC code + .label VARTAB = $2D // $2D-$2E end of BASIC code, start of variables + .label ARYTAB = $2F // $2F-$30 -- NOT IMPLEMENTED -- + .label STREND = $31 // $31-$32 -- NOT IMPLEMENTED -- + .label FRETOP = $33 // $33-$34 -- NOT IMPLEMENTED -- + .label FRESPC = $35 // $35-$36 [!] our implementation might be different XXX give more details + // .label MEMSIZ = $37 // $37-$38 -- NOT IMPLEMENTED -- highest address of BASIC memory XXX remove name conflict + .label CURLIN = $39 // $39-$3A current BASIC line number + .label OLDLIN = $3B // $3B-$3C previous BASIC line number + .label OLDTXT = $3D // $3D-$3E current BASIC line pointer + .label DATLIN = $3F // $3F-$40 -- NOT IMPLEMENTED -- + .label DATPTR = $41 // $41-$42 -- NOT IMPLEMENTED -- + .label INPPTR = $43 // $43-$44 -- NOT IMPLEMENTED -- + .label VARNAM = $45 // $45-$46 -- NOT IMPLEMENTED -- + .label VARPNT = $47 // $47-$48 -- NOT IMPLEMENTED -- + .label FORPNT = $49 // $49-$4A -- NOT IMPLEMENTED -- + .label OPPTR = $4B // $4B-$4C -- NOT IMPLEMENTED -- + .label OPMASK = $4D // -- NOT IMPLEMENTED -- + .label DEFPNT = $4E // $4E-$4F -- NOT IMPLEMENTED -- + .label DSCPNT = $50 // $50-$52 -- NOT IMPLEMENTED -- + .label FOUR6 = $53 // -- NOT IMPLEMENTED -- + .label JMPER = $54 // $54-$56 -- NOT IMPLEMENTED -- + .label TEMPF1 = $57 // $57-$5B BASIC numeric work area + .label TEMPF2 = $5C // $5C-$60 BASIC numeric work area + .label FAC1 = $61 // $61-$66 -- NOT IMPLEMENTED -- + .label SGNFLG = $67 // -- NOT IMPLEMENTED -- + .label BITS = $68 // -- NOT IMPLEMENTED -- + .label FAC2 = $69 // $69-$6E -- NOT IMPLEMENTED -- [!] also used for memory move pointers + .label ARISGN = $6F // -- NOT IMPLEMENTED -- + .label FACOV = $70 // -- NOT IMPLEMENTED -- + .label FBUFPT = $67 // $71-$72 -- NOT IMPLEMENTED -- + .label CHRGET = $73 // $73-$8A -- NOT IMPLEMENTED -- + .label TXTPTR = $7A // $7A-$7B current BASIC statement pointer + .label RNDX = $8B // $8B-$8F -- NOT IMPLEMENTED -- + + // + // Page 0 - Kernal area ($90-$FF) + // - .alias TXTTAB $2B + .label IOSTATUS = $90 + .label STKEY = $91 // Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2 + .label SVXT = $92 // -- NOT IMPLEMENTED -- + .label VERCK = $93 // 0 = LOAD, 1 = VERIFY XXX rename to VERCKK + .label C3PO = $94 // flag - is BSOUR content valid + .label BSOUR = $95 // serial bus buffered output byte + .label SYNO = $96 // -- NOT IMPLEMENTED -- + .label XSAV = $97 // -- NOT IMPLEMENTED -- + .label LDTND = $98 // number of entries in LAT / FAT / SAT tables + .label DFLTN = $99 // default input device + .label DFLTO = $9A // default output device + .label PRTY = $9B // -- NOT IMPLEMENTED -- + .label DPSW = $9C // -- NOT IMPLEMENTED -- + .label MSGFLG = $9D // bit 6 = error messages, bit 7 = control message + .label PTR1 = $9E // -- NOT IMPLEMENTED -- + .label PTR2 = $9F // -- NOT IMPLEMENTED -- + .label TIME = $A0 // $A0-$A2, jiffy clock + .label IEC_TMP1 = $A3 // temporary variable for tape and IEC, [!] our usage probably differs in details XXX rename to TSFCNT + .label IEC_TMP2 = $A4 // temporary variable for tape and IEC, [!] our usage probably differs in details XXX rename to TBTCNT + .label CNTDN = $A5 // -- NOT IMPLEMENTED -- + .label BUFPNT = $A6 // -- NOT IMPLEMENTED -- + .label INBIT = $A7 // -- NOT IMPLEMENTED -- + .label BITCI = $A8 // -- NOT IMPLEMENTED -- + .label RINONE = $A9 // -- NOT IMPLEMENTED -- + .label RIDDATA = $AA // -- NOT IMPLEMENTED -- + .label RIPRTY = $AB // -- NOT IMPLEMENTED -- + .label SAL = $AC // $AC-$AD -- NOT IMPLEMENTED -- (implemented screen part) + .label EAL = $AE // $AE-$AF -- NOT IMPLEMENTED -- [!] used also byy screen editor + .label CMP0 = $B0 // $B0-$B1, temporary tape storage, [!] here used for BRK instruction address + .label TAPE1 = $B2 // $B2-$B3 tape buffer pointer + .label BITTS = $B4 // -- NOT IMPLEMENTED -- + .label NXTBIT = $B5 // -- NOT IMPLEMENTED -- + .label RODATA = $B6 // -- NOT IMPLEMENTED -- + .label FNLEN = $B7 // current file name length + .label LA = $B8 // current logical_file number + .label SA = $B9 // current secondary address + .label FA = $BA // current device number + .label FNADDR = $BB // $BB-$BC, current file name pointer + .label ROPRTY = $BD // -- NOT IMPLEMENTED -- + .label FSBLK = $BE // -- NOT IMPLEMENTED -- + .label MYCH = $BF // -- NOT IMPLEMENTED -- + .label CAS1 = $C0 // -- NOT IMPLEMENTED -- + .label STAL = $C1 // $C1-$C2, LOAD/SAVE start address + .label MEMUS = $C3 // $C3-$C4, temporary address for tape LOAD/SAVE XXX rename to MEMUSS + .label LSTX = $C5 // last keyy matrix position [!] our usage probably differs in details + .label NDX = $C6 // number of chars in keyboard buffer + .label RVS = $C7 // flag, whether to print reversed characters + .label INDX = $C8 // end of logical line (column, 0-79) + .label LXSP = $C9 // $C9-$CA start of input, X/Y position + .label SFDX = $CB // -- NOT IMPLEMENTED -- + .label BLNSW = $CC // cursor blink disable flag + .label BLNCT = $CD // cursor blink countdown + .label GDBLN = $CE // cursorb saved character + .label BLNON = $CF // cursor visibilityy flag + .label CRSW = $D0 // whether to input from screen or keyboard + .label PNT = $D1 // $D1-$D2 pointer to the current screen line + .label PNTR = $D3 // current screen X position + .label QTSW = $D4 // quote mode flag + .label LNMX = $D5 // logical line length, [!] our usage probably differs in details + .label TBLX = $D6 // current screen Y position + .label SCHAR = $D7 // ASCII value of the last printed character + .label INSRT = $D8 // insert mode flag/counter + .label LDTB1 = $D9 // $D9-$F2 screen line link table, [!] our usage is different XXX give more details + .label USER = $F3 // $F3-$F4 pointer to current color RAM location + .label KEYTAB = $F5 // $F5-$F6 -- NOT IMPLEMENTED -- + .label RIBUF = $F7 // $F7-$F8 -- NOT IMPLEMENTED -- + .label ROBUF = $F9 // $F9-$FA -- NOT IMPLEMENTED -- + // $FB $FB-$FE -- UNUSED -- free for user software + .label BASZPT = $FF // -- NOT IMPLEMENTED -- - ;; - ;; Page 0 - Kernal area ($90-$FF) - ;; - - .alias IOSTATUS $90 - .alias STKEY $91 ; Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2 - - .alias VERCK $93 ; 0 = LOAD, 1 = VERIVY - - .alias C3PO $94 ; flag - is BSOUR content valid - .alias BSOUR $95 ; serial bus buffered output byte + // + // Page 1 + // - .alias LDTND $98 ; number of entries in LAT / FAT / SAT tables - .alias DFLTN $99 - .alias DFLTO $9A - - .alias MSGFLG $9D ; bit 6 = error messages, bit 7 = control message + .label STACK = $100 // $100-$1FF, processor stack - .alias TIME $A0 ; $A0-$A2, jiffy clock - - .alias IEC_TMP1 $A3 ; temporary variable for tape and IEC - .alias IEC_TMP2 $A4 ; temporary variable for tape and IEC - - .alias CMP0 $B0 ; $B0-$B1, temporary tape storage, we use it too for BRK instruction address - - .alias FNLEN $B7 ; current file name length - - .alias FNADDR $BB ; $BB-$BC, current file name pointer - - .alias STAL $C1 ; $C1-$C2 LOAD/SAVE start address - .alias MEMUS $C3 ; $C3-$C4 temporary address for tape LOAD/SAVE - - ;; - ;; Other low memory addresses - ;; + // + // Pages 2 & 3 + // - .alias BUF $200 ; $200-$250 (81 bytes), BASIC line editor input buffer + .label BUF = $200 // $200-$250, BASIC line editor input buffer (81 bytes) + // [!] XXX document $251-$258 usage + .label LAT = $259 // $259-$262, logical file numbers (table, 10 bytes) + .label FAT = $263 // $263-$26C, device numbers (table, 10 bytes) + .label SAT = $26D // $26D-$276, secondary addresses (table, 10 bytes) + .label KEYD = $277 // $277-$280 keyboard buffer + .label MEMSTR = $281 // $281-$282 XXX rename to LORAM + .label MEMSIZ = $283 // $283-$284, NOTE: Mapping the 64 erroneously has the hex as $282, while the DEC is correct XXX rename to HIRAM + .label TIMOUT = $285 // IEEE-488 timeout + .label COLOR = $286 // current text foreground color + .label GDCOL = $287 // color of character under cursor + .label HIBASE = $288 // high byte of start of screen + .label XMAX = $289 // max keyboard buffer size + .label RPTFLG = $28A // -- NOT IMPLEMENTED -- + .label KOUNT = $28B // -- NOT IMPLEMENTED -- + .label DELAY = $28C // -- NOT IMPLEMENTED -- + .label SHFLAG = $28D // bucky keys (SHIFT/CTRL/C=) flags + .label LSTSHF = $28E // last bucky key flags + .label KEYLOG = $28F // $28F-$290 -- NOT IMPLEMENTED -- + .label MODE = $291 // flag, is case switch allowed + .label AUTODN = $292 // -- NOT IMPLEMENTED -- + .label M51CRT = $293 // -- NOT IMPLEMENTED -- mock 6551 + .label M51CDR = $294 // -- NOT IMPLEMENTED -- mock 6551 + .label M51AJB = $295 // $295-$296 -- NOT IMPLEMENTED -- mock 6551 + .label RSSTAT = $297 // -- NOT IMPLEMENTED -- mock 6551, RS-232 status + .label BITNUM = $298 // -- NOT IMPLEMENTED -- + .label BAUDOF = $299 // $299-$29A -- NOT IMPLEMENTED -- + .label RIDBE = $29B // -- NOT IMPLEMENTED -- + .label RIDBS = $29C // -- NOT IMPLEMENTED -- + .label RODBS = $29D // -- NOT IMPLEMENTED -- + .label RODBE = $29E // -- NOT IMPLEMENTED -- + .label IRQTMP = $29F // $29F-$2A0 -- NOT IMPLEMENTED -- + .label ENABL = $2A1 // -- NOT IMPLEMENTED -- + .label TODSNS = $2A2 // -- NOT IMPLEMENTED -- + .label TRDTMP = $2A3 // -- NOT IMPLEMENTED -- + .label TD1IRQ = $2A4 // -- NOT IMPLEMENTED -- + .label TLNIDX = $2A5 // -- NOT IMPLEMENTED -- + .label PALNTSC = $2A6 // 0 = NTSC, 1 = PAL XXX rename to TVSFLG + // [!] XXX document $2A7-$2FF usage - ;; Kernal tables for opened files, 10 entries each - .alias LAT $259 ; logical file numbers - .alias FAT $263 ; device numbers - .alias SAT $26D ; secondary addresses - - .alias MEMSTR $281 - .alias MEMSIZ $283 ; NOTE: Mapping the 64 erroniously has the hex as $282, while the DEC is correct - - .alias TIMOUT $285 ; IEEE-488 timeout - - .alias HIBASE $288 ; high byte of start of screen - - .alias RSSTAT $297 ; RS-232 status - - .alias PALNTSC $2A6 ; 0 = NTSC, 1 = PAL + // BASIC vectors + .label IERROR = $300 // $300-$301 -- NOT IMPLEMENTED -- + .label IMAIN = $302 // $302-$303 -- NOT IMPLEMENTED -- + .label ICRNCH = $304 // $304-$305 -- NOT IMPLEMENTED -- + .label IQPLOP = $306 // $306-$307 -- NOT IMPLEMENTED -- + .label IGONE = $308 // $308-$309 -- NOT IMPLEMENTED -- + .label IEVAL = $30A // $30A-$30B -- NOT IMPLEMENTED -- - - ;; Registers for SYS call - .alias SAREG $30C - .alias SXREG $30D - .alias SYREG $30E - .alias SPREG $30F + .label SAREG = $30C // .A storage, for SYS call + .label SXREG = $30D // .X storage, for SYS call + .label SYREG = $30E // .Y storage, for SYS call + .label SPREG = $30F // .P storage, for SYS call - .alias USRPOK $310 ; JMP instruction - .alias USRADD $311 ; $311 - $312 + .label USRPOK = $310 // -- NOT IMPLEMENTED -- JMP instruction + .label USRADD = $311 // $311-$312 -- NOT IMPLEMENTED -- + // $313 -- UNUSED -- free for user software - ;; Kernal vectors - interrupts - .alias CINV $314 - .alias CBINV $316 - .alias NMINV $318 + // Kernal vectors - interrupts + .label CINV = $314 // $314-$315 + .label CBINV = $316 // $316-$317 + .label NMINV = $318 // $318-$319 - ;; Kernal vectors - routines - .alias IOPEN $31A - .alias ICLOSE $31C - .alias ICHKIN $31E - .alias ICKOUT $320 - .alias ICLRCH $322 - .alias IBASIN $324 - .alias IBSOUT $326 - .alias ISTOP $328 - .alias IGETIN $32A - .alias ICLALL $32C - .alias USRCMD $32E - .alias ILOAD $330 - .alias ISAVE $331 + // Kernal vectors - routines + .label IOPEN = $31A // $31A-$31B + .label ICLOSE = $31C // $31C-$31D + .label ICHKIN = $31E // $31E-$31F + .label ICKOUT = $320 // $320-$321 + .label ICLRCH = $322 // $322-$323 + .label IBASIN = $324 // $324-$325 + .label IBSOUT = $326 // $326-$327 + .label ISTOP = $328 // $328-$329 + .label IGETIN = $32A // $32A-$32B + .label ICLALL = $32C // $32C-$32D + .label USRCMD = $32E // $32E-$32F + .label ILOAD = $330 // $330-$331 + .label ISAVE = $332 // $332-$333 - .alias TBUFFR $33C ; $33C-$3FB, tape buffer + // $314 $334-$33B -- UNUSED -- free for user software + + .label TBUFFR = $33C // $33C-$3FB, -- NOT IMPLEMENTED --, tape buffer + + // $3FC $3FC-$3FF -- UNUSED -- free for user software diff --git a/c64/aliases/,aliases_rom_basic.s b/c64/aliases/,aliases_rom_basic.s index ff6c46dc..67aa954d 100644 --- a/c64/aliases/,aliases_rom_basic.s +++ b/c64/aliases/,aliases_rom_basic.s @@ -1,5 +1,4 @@ - ;; BASIC startup vector - - .alias IBASIC_COLD_START $A000 - .alias IBASIC_WARM_START $A002 + // BASIC startup vectors + .label IBASIC_COLD_START = $A000 + .label IBASIC_WARM_START = $A002 diff --git a/c64/aliases/,aliases_rom_cart.s b/c64/aliases/,aliases_rom_cart.s index c2e25c1e..50decc3f 100644 --- a/c64/aliases/,aliases_rom_cart.s +++ b/c64/aliases/,aliases_rom_cart.s @@ -1,5 +1,5 @@ - ;; Cartridge ROM locations - .alias ICART_COLD_START $8000 ; $8000-$8001, cartridge cold start vector - .alias ICART_WARM_START $8002 ; $8002-$8003, cartridge warm start vector (RESTORE key) - .alias CART_SIG $8004 ; 5 bytes, signature for cartridge detection + // Cartridge ROM locations + .label ICART_COLD_START = $8000 // $8000-$8001, cartridge cold start vector + .label ICART_WARM_START = $8002 // $8002-$8003, cartridge warm start vector (RESTORE key) + .label CART_SIG = $8004 // $8004-$8008, signature for cartridge detection diff --git a/c64/aliases/,aliases_rom_kernal.s b/c64/aliases/,aliases_rom_kernal.s index 91c601d9..35e89d07 100644 --- a/c64/aliases/,aliases_rom_kernal.s +++ b/c64/aliases/,aliases_rom_kernal.s @@ -1,41 +1,41 @@ - ;; Kernal jump table - .alias JCINT $FF81 - .alias JIOINIT $FF84 - .alias JRAMTAS $FF87 - .alias JRESTOR $FF8A - .alias JVECTOR $FF8D - .alias JSETMSG $FF90 - .alias JSECOND $FF93 - .alias JTKSA $FF96 - .alias JMEMTOP $FF99 - .alias JMEMBOT $FF9C - .alias JSCNKEY $FF9F - .alias JSETTMO $FFA2 - .alias JACPTR $FFA5 - .alias JCIOUT $FFA8 - .alias JUNTLK $FFAB - .alias JUNLSN $FFAE - .alias JLISTEN $FFB1 - .alias JTALK $FFB4 - .alias JREADST $FFB7 - .alias JSETFLS $FFBA - .alias JSETNAM $FFBD - .alias JOPEN $FFC0 - .alias JCLOSE $FFC3 - .alias JCHKIN $FFC6 - .alias JCKOUT $FFC9 - .alias JCLRCHN $FFCC - .alias JCHRIN $FFCF - .alias JCHROUT $FFD2 - .alias JLOAD $FFD5 - .alias JSAVE $FFD8 - .alias JSETTIM $FFDB - .alias JRDTIM $FFDE - .alias JSTOP $FFE1 - .alias JGETIN $FFE4 - .alias JCLALL $FFE7 - .alias JUDTIM $FFEA - .alias JSCREEN $FFED - .alias JPLOT $FFF0 - .alias JIOBASE $FFF3 + // Kernal jump table + .label JCINT = $FF81 + .label JIOINIT = $FF84 + .label JRAMTAS = $FF87 + .label JRESTOR = $FF8A + .label JVECTOR = $FF8D + .label JSETMSG = $FF90 + .label JSECOND = $FF93 + .label JTKSA = $FF96 + .label JMEMTOP = $FF99 + .label JMEMBOT = $FF9C + .label JSCNKEY = $FF9F + .label JSETTMO = $FFA2 + .label JACPTR = $FFA5 + .label JCIOUT = $FFA8 + .label JUNTLK = $FFAB + .label JUNLSN = $FFAE + .label JLISTEN = $FFB1 + .label JTALK = $FFB4 + .label JREADST = $FFB7 + .label JSETFLS = $FFBA + .label JSETNAM = $FFBD + .label JOPEN = $FFC0 + .label JCLOSE = $FFC3 + .label JCHKIN = $FFC6 + .label JCKOUT = $FFC9 + .label JCLRCHN = $FFCC + .label JCHRIN = $FFCF + .label JCHROUT = $FFD2 + .label JLOAD = $FFD5 + .label JSAVE = $FFD8 + .label JSETTIM = $FFDB + .label JRDTIM = $FFDE + .label JSTOP = $FFE1 + .label JGETIN = $FFE4 + .label JCLALL = $FFE7 + .label JUDTIM = $FFEA + .label JSCREEN = $FFED + .label JPLOT = $FFF0 + .label JIOBASE = $FFF3 diff --git a/c64/basic/,aliases.s b/c64/basic/,aliases.s index e54dd5a9..a626522d 100644 --- a/c64/basic/,aliases.s +++ b/c64/basic/,aliases.s @@ -1,126 +1,128 @@ -; Names of ZP and low memory locations -; (Only those for now that we feel the need to implement initially) -; (https://www.c64-wiki.com/wiki/Zeropage) +// Names of ZP and low memory locations +// (Only those for now that we feel the need to implement initially) +// (https://www.c64-wiki.com/wiki/Zeropage) - .alias tokenise_work1 $7 - .alias tokenise_work2 $8 - .alias tokenise_work3 $B - .alias tokenise_work4 $F - .alias basic_line_number $14 - .alias temp_string_ptr $35 - .alias load_or_verify_or_tokenise_work5 $C - .alias basic_work22 $22 - .alias basic_work23 $23 - .alias basic_work24 $24 - .alias basic_work25 $25 +// XXX get rid of this file, use ,aliases_ram_lowmem.s instead - ;; The various pointers that separate memory regions for BASIC storage - ;; We have multiple names for the ones that mark the boundary of regions. - .alias basic_start_of_text_ptr $2b - .alias basic_end_of_text_ptr $2d - .alias basic_start_of_vars_ptr $2d - .alias basic_end_of_vars_ptr $2f - .alias basic_start_of_arrays_ptr $2f - .alias basic_end_of_arrays_ptr $31 - .alias basic_start_of_free_space_ptr $31 - .alias basic_start_of_strings_ptr $33 - .alias basic_top_of_memory_ptr $37 - .alias basic_current_line_number $39 - .alias basic_previous_line_number $3b - .alias basic_current_line_ptr $3d + .label tokenise_work1 = $7 + .label tokenise_work2 = $8 + .label tokenise_work3 = $B + .label tokenise_work4 = $F + .label basic_line_number = $14 + .label temp_string_ptr = $35 + .label load_or_verify_or_tokenise_work5 = $C + .label basic_work22 = $22 + .label basic_work23 = $23 + .label basic_work24 = $24 + .label basic_work25 = $25 - ;; Note that the statement point is in the CHRGET/CHRGOT routine - ;; in ZP RAM. (Compute's Mapping the 64, p25) - .alias basic_current_statement_ptr $7a + // The various pointers that separate memory regions for BASIC storage + // We have multiple names for the ones that mark the boundary of regions. + .label basic_start_of_text_ptr = $2b + .label basic_end_of_text_ptr = $2d + .label basic_start_of_vars_ptr = $2d + .label basic_end_of_vars_ptr = $2f + .label basic_start_of_arrays_ptr = $2f + .label basic_end_of_arrays_ptr = $31 + .label basic_start_of_free_space_ptr = $31 + .label basic_start_of_strings_ptr = $33 + .label basic_top_of_memory_ptr = $37 + .label basic_current_line_number = $39 + .label basic_previous_line_number = $3b + .label basic_current_line_ptr = $3d + + // Note that the statement point is in the CHRGET/CHRGOT routine + // in ZP RAM. (Compute's Mapping the 64, p25) + .label basic_current_statement_ptr = $7a - .alias basic_numeric_work_area $57 ; $57 - $60 inclusive = 10 bytes + .label basic_numeric_work_area = $57 // $57 - $60 inclusive = 10 bytes - ;; Floating point accumulator 1 $61 - $68 - .alias basic_fac1_exponent $61 - .alias basic_fac1_mantissa $62 ; $62 - $65 - .alias basic_fac1_sign $66 - .alias basic_fac1_overflow $68 - .alias basic_fac1_mantissa_lob $70 + // Floating point accumulator 1 $61 - $68 + .label basic_fac1_exponent = $61 + .label basic_fac1_mantissa = $62 // $62 - $65 + .label basic_fac1_sign = $66 + .label basic_fac1_overflow = $68 + .label basic_fac1_mantissa_lob = $70 - .alias basic_fac2_exponent $69 - .alias basic_fac2_mantissa $6A ; $6A - $6D - .alias basic_fac2_sign $6E + .label basic_fac2_exponent = $69 + .label basic_fac2_mantissa = $6A // $6A - $6D + .label basic_fac2_sign = $6E - ;; We also re-use FAC2 for memory move pointers, since - ;; we can't be doing calculations while moving memory - .alias memmove_src $69 - .alias memmove_dst $6b - .alias memmove_size $6d + // We also re-use FAC2 for memory move pointers, since + // we can't be doing calculations while moving memory + .label memmove_src = $69 + .label memmove_dst = $6b + .label memmove_size = $6d - .alias current_file_num $98 - .alias cassette_buffer_bytes_used $A6 - .alias load_or_scroll_temp_pointer $AC - ;; We also use the following for temp colour pointer when scrolling - .alias load_save_verify_end_address $AE + .label current_file_num = $98 + .label cassette_buffer_bytes_used = $A6 + .label load_or_scroll_temp_pointer = $AC + // We also use the following for temp colour pointer when scrolling + .label load_save_verify_end_address = $AE - .alias cassette_buffer_ptr $B2 - .alias current_logical_filenum $B8 - .alias current_secondary_address $B9 - .alias current_device_number $BA - .alias current_filename_ptr $BB - .alias load_save_start_ptr $C1 - .alias load_save_end_ptr $C3 - .alias last_key_matrix_position $C5 - .alias keys_in_key_buffer $C6 - .alias reverse_video_flag $C7 - .alias end_of_input_line $C8 - .alias start_of_keyboard_input $C9 - .alias current_key_index_entry $CB - .alias cursor_blink_disable $CC - .alias cursor_blink_countdown $CD - .alias cursor_saved_character $CE - .alias cursor_is_visible $CF - .alias keyboard_input_ready $D0 - .alias current_screen_line_ptr $D1 - .alias current_screen_x $D3 - .alias quote_mode_flag $D4 - .alias logical_line_length $D5 - .alias current_screen_y $D6 - .alias last_printed_character_ascii $D7 - .alias insert_mode $D8 - ; Bits 0 -3 = bits 8-11 of screen line address - ; Bit 7 = line spans multiple physical lines - .alias screen_line_link_table $D9 - .alias current_screen_line_colour_ptr $F3 - .alias keyboard_decoding_table_ptr $F5 - .alias rs232_rx_buffer_ptr $F7 - .alias rs232_tx_buffer_ptr $F9 + .label cassette_buffer_ptr = $B2 + .label current_logical_filenum = $B8 + .label current_secondary_address = $B9 + .label current_device_number = $BA + .label current_filename_ptr = $BB + .label load_save_start_ptr = $C1 + .label load_save_end_ptr = $C3 + .label last_key_matrix_position = $C5 + .label keys_in_key_buffer = $C6 + .label reverse_video_flag = $C7 + .label end_of_input_line = $C8 + .label start_of_keyboard_input = $C9 + .label current_key_index_entry = $CB + .label cursor_blink_disable = $CC + .label cursor_blink_countdown = $CD + .label cursor_saved_character = $CE + .label cursor_is_visible = $CF + .label keyboard_input_ready = $D0 + .label current_screen_line_ptr = $D1 + .label current_screen_x = $D3 + .label quote_mode_flag = $D4 + .label logical_line_length = $D5 + .label current_screen_y = $D6 + .label last_printed_character_ascii = $D7 + .label insert_mode = $D8 + // Bits 0 -3 = bits 8-11 of screen line address + // Bit 7 = line spans multiple physical lines + .label screen_line_link_table = $D9 + .label current_screen_line_colour_ptr = $F3 + .label keyboard_decoding_table_ptr = $F5 + .label rs232_rx_buffer_ptr = $F7 + .label rs232_tx_buffer_ptr = $F9 - .alias basic_input_buffer BUF - - ; "Compute's Mapping the 64" book - .alias keyboard_buffer $0277 - .alias text_colour $0286 ; p55 - .alias colour_under_cursor $0287 ; p56 - .alias key_buffer_size $0289 ; p57 + .label basic_input_buffer = BUF - ;; 0 = cursor keys, insert, delete and space repeat, but nothing else - ;; 128 = all keys repeat - ;; 64 = no keys repeat - .alias key_repeat_flags $028A ; p58 - ;; https://www.c64-wiki.com/wiki/Page_2 - .alias key_repeat_counter $028B - .alias key_first_repeat_delay $028C - ;; bit 0 = shift, 1 = Vendor Key, 2 = Control - .alias key_bucky_state $028D - .alias key_last_bucky_state $028E - .alias keyboard_decoding_ptr $028F - .alias enable_case_switch $0291 - .alias screen_scroll_disable $0292 + // "Compute's Mapping the 64" book + .label keyboard_buffer = $0277 + .label text_colour = $0286 // p55 + .label colour_under_cursor = $0287 // p56 + .label key_buffer_size = $0289 // p57 - ;; BASIC uses some extra bytes for memory access under ROMs located at $2A7 onwards - ;; IRQs are disabled when doing such accesses, and a default NMI handler only increments - ;; a counter, so that if an NMI occurs, it doesn't crash the machine, but can be captured. - .alias missed_nmi_flag $2A7 - .alias tiny_nmi_handler $2A8 - .alias shift_mem_up tiny_nmi_handler+shift_mem_up_routine-tiny_nmi_handler_routine - .alias shift_mem_down tiny_nmi_handler+shift_mem_down_routine-tiny_nmi_handler_routine - .alias peek_under_roms tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine - .alias poke_under_roms tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine - .alias memmap_allram tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine - .alias memmap_normal tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine + // 0 = cursor keys, insert, delete and space repeat, but nothing else + // 128 = all keys repeat + // 64 = no keys repeat + .label key_repeat_flags = $028A // p58 + // https://www.c64-wiki.com/wiki/Page_2 + .label key_repeat_counter = $028B + .label key_first_repeat_delay = $028C + // bit 0 = shift, 1 = Vendor Key, 2 = Control + .label key_bucky_state = $028D + .label key_last_bucky_state = $028E + .label keyboard_decoding_ptr = $028F + .label enable_case_switch = $0291 + .label screen_scroll_disable = $0292 + + // BASIC uses some extra bytes for memory access under ROMs located at $2A7 onwards + // IRQs are disabled when doing such accesses, and a default NMI handler only increments + // a counter, so that if an NMI occurs, it doesn't crash the machine, but can be captured. + .label missed_nmi_flag = $2A7 + .label tiny_nmi_handler = $2A8 + .label shift_mem_up = tiny_nmi_handler+shift_mem_up_routine-tiny_nmi_handler_routine + .label shift_mem_down = tiny_nmi_handler+shift_mem_down_routine-tiny_nmi_handler_routine + .label peek_under_roms = tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine + .label poke_under_roms = tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine + .label memmap_allram = tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine + .label memmap_normal = tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine diff --git a/c64/basic/,target_generic/,hooks_generic.s b/c64/basic/,target_generic/,hooks_generic.s index 92860379..c87cffd9 100644 --- a/c64/basic/,target_generic/,hooks_generic.s +++ b/c64/basic/,target_generic/,hooks_generic.s @@ -1,9 +1,10 @@ -;; Target-specific hooks +// Target-specific hooks -.macro TARGET_HOOK_BANNER +.macro TARGET_HOOK_BANNER() { - .byte " OPEN ROMS, ", $00 + .text " OPEN ROMS, " + .byte $00 -.macend +} diff --git a/c64/basic/,target_mega65/,hooks_mega65.s b/c64/basic/,target_mega65/,hooks_mega65.s index 97c859e5..07b2b58e 100644 --- a/c64/basic/,target_mega65/,hooks_mega65.s +++ b/c64/basic/,target_mega65/,hooks_mega65.s @@ -1,10 +1,10 @@ -;; Target-specific hooks +// Target-specific hooks -.macro TARGET_HOOK_BANNER +.macro TARGET_HOOK_BANNER() { - ;; New banner from Retrofan + // New banner from Retrofan .byte $9a, $12, $20, $20, $7f, $a9, $20, $20, $1f, $20, $9a, $20, $20, $20 .byte $20, $1f, $20, $9a, $a9, $20, $20, $20, $92, $a1, $1f, $12, $20, $9a, $a9, $20 .byte $20, $20, $7f, $1f, $20, $20, $9a, $a3, $a3, $a3, $a3, $a3, $a3, $a3, $1f, $20 @@ -21,21 +21,21 @@ .byte $20, $20, $1f, $20, $20, $96, $a3, $a3, $a3, $a3, $1f .byte $92, $0D, $0D, $05, $00 - ;; Original Deft-supplied banner - ;; .byte $9A,$12,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$20,$05,$12,$A0,$A0 - ;; .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9B,$92,$20,$05,$12,$A0,$A0 - ;; .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9A,$92,$20,$05,$20,$20,$20 - ;; .byte $4D,$20,$45,$20,$47,$20,$41,$0D,$99,$12,$A3,$A3,$A3,$A3,$A3,$A3 - ;; .byte $A3,$DF,$92,$7F,$12,$CD,$CD,$DF,$92,$7F,$12,$DF,$05,$92,$20,$20 - ;; .byte $99,$7F,$12,$DF,$05,$92,$20,$20,$99,$7F,$12,$DF,$92,$7F,$12,$DF - ;; .byte $05,$92,$20,$20,$99,$42,$20,$41,$20,$53,$20,$49,$20,$43,$0D,$9E - ;; .byte $12,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$7F,$12,$DF,$92 - ;; .byte $7F,$12,$DF,$92,$7F,$12,$CD,$05,$92,$20,$20,$9B,$7F,$12,$CD,$92 - ;; .byte $7F,$12,$DF,$92,$7F,$12,$CD,$92,$7F,$12,$DF,$9A,$92,$20,$05,$20 - ;; .byte $9A,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$0D,$96,$12,$A3,$A3,$A3,$A3,$A3 - ;; .byte $A3,$A3,$A3,$A3,$DF,$9A,$92,$7F,$12,$DF,$92,$7F,$9B,$20,$9A,$7F - ;; .byte $12,$A0,$A0,$9B,$92,$20,$9A,$7F,$12,$A0,$A0,$9B,$92,$20,$9A,$7F - ;; .byte $12,$DF,$92,$7F,$9B,$20,$9A,$20,$9B,"0.2.0.0",$0D - ;; .byte $0D,$05,$92,$00 + // Original Deft-supplied banner + // .byte $9A,$12,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$20,$05,$12,$A0,$A0 + // .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9B,$92,$20,$05,$12,$A0,$A0 + // .byte $DF,$9B,$92,$20,$05,$12,$A0,$A0,$DF,$9A,$92,$20,$05,$20,$20,$20 + // .byte $4D,$20,$45,$20,$47,$20,$41,$0D,$99,$12,$A3,$A3,$A3,$A3,$A3,$A3 + // .byte $A3,$DF,$92,$7F,$12,$CD,$CD,$DF,$92,$7F,$12,$DF,$05,$92,$20,$20 + // .byte $99,$7F,$12,$DF,$05,$92,$20,$20,$99,$7F,$12,$DF,$92,$7F,$12,$DF + // .byte $05,$92,$20,$20,$99,$42,$20,$41,$20,$53,$20,$49,$20,$43,$0D,$9E + // .byte $12,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$A3,$DF,$9B,$92,$7F,$12,$DF,$92 + // .byte $7F,$12,$DF,$92,$7F,$12,$CD,$05,$92,$20,$20,$9B,$7F,$12,$CD,$92 + // .byte $7F,$12,$DF,$92,$7F,$12,$CD,$92,$7F,$12,$DF,$9A,$92,$20,$05,$20 + // .byte $9A,$2D,$2D,$2D,$2D,$2D,$2D,$2D,$0D,$96,$12,$A3,$A3,$A3,$A3,$A3 + // .byte $A3,$A3,$A3,$A3,$DF,$9A,$92,$7F,$12,$DF,$92,$7F,$9B,$20,$9A,$7F + // .byte $12,$A0,$A0,$9B,$92,$20,$9A,$7F,$12,$A0,$A0,$9B,$92,$20,$9A,$7F + // .byte $12,$DF,$92,$7F,$9B,$20,$9A,$20,$9B,"0.2.0.0",$0D + // .byte $0D,$05,$92,$00 -.macend +} diff --git a/c64/basic/,target_ultimate64/,hooks_ultimate64.s b/c64/basic/,target_ultimate64/,hooks_ultimate64.s index 9ae05e35..985ea57d 100644 --- a/c64/basic/,target_ultimate64/,hooks_ultimate64.s +++ b/c64/basic/,target_ultimate64/,hooks_ultimate64.s @@ -1,9 +1,12 @@ -;; Target-specific hooks +// Target-specific hooks -.macro TARGET_HOOK_BANNER +.macro TARGET_HOOK_BANNER() { - .byte " OPEN ROMS FOR ULTIMATE 64", $0D, $0D, " ", $00 + .text " OPEN ROMS FOR ULTIMATE 64" + .byte $0D, $0D + .text " " + .byte $00 -.macend +} diff --git a/c64/basic/a000.cold_start_vector.s b/c64/basic/a000.cold_start_vector.s index 863ffec8..7ed2cb76 100644 --- a/c64/basic/a000.cold_start_vector.s +++ b/c64/basic/a000.cold_start_vector.s @@ -1,3 +1,4 @@ - ;; Compute's Mapping the C64 p88 +// Compute's Mapping the C64 p88 + .word basic_cold_start - + diff --git a/c64/basic/a002.warm_start_vector.s b/c64/basic/a002.warm_start_vector.s index aa16bda1..63c4d2a5 100644 --- a/c64/basic/a002.warm_start_vector.s +++ b/c64/basic/a002.warm_start_vector.s @@ -1,2 +1,3 @@ - ;; Compute's Mapping the C64 p88 +// Compute's Mapping the C64 p88 + .word basic_warm_start diff --git a/c64/basic/a004.identifier.s b/c64/basic/a004.identifier.s index 74e9d6fe..88cbb600 100644 --- a/c64/basic/a004.identifier.s +++ b/c64/basic/a004.identifier.s @@ -1,6 +1,6 @@ - ;; Compute's Mapping the 64, p89 - ;; 8 character name - ;; MEGABAS2 = "MEGA BASIC 2" +// Compute's Mapping the 64, p89 +// 8 character name +// MEGABAS2 = "MEGA BASIC 2" + .byte $4D,$45,$47,$41,$42,$41,$53,$32 - - + diff --git a/c64/basic/ab1e.print_string.s b/c64/basic/ab1e.print_string.s index 0ea252a3..360e95c5 100644 --- a/c64/basic/ab1e.print_string.s +++ b/c64/basic/ab1e.print_string.s @@ -1,19 +1,19 @@ - ;; Print string at $YYAA - ;; Compute's Mapping the 64 p101 +// Print string at $YYAA +// Compute's Mapping the 64 p101 print_string: - ;; Setup pointer + // Setup pointer sty temp_string_ptr+1 sta temp_string_ptr+0 - txa + txa pha - ;; Get offset ready + // Get offset ready ldy #$00 print_string_loop: - ;; Save Y in X, since X is preserved by chrout, but Y is not + // Save Y in X, since X is preserved by chrout, but Y is not tya tax @@ -28,7 +28,6 @@ print_string_loop: iny bne print_string_loop - print_string_end: pla diff --git a/c64/basic/basic_cold_start.s b/c64/basic/basic_cold_start.s index b57145c8..ac1f507c 100644 --- a/c64/basic/basic_cold_start.s +++ b/c64/basic/basic_cold_start.s @@ -1,31 +1,31 @@ - ;; BASIC Cold start entry point - ;; Compute's Mapping the 64 p211 +// BASIC Cold start entry point +// Compute's Mapping the 64 p211 basic_cold_start: - ;; Setup BASIC vectors at $0300 - ;; Initialise interpretor - ;; Print start up message + // Setup BASIC vectors at $0300 + // Initialise interpretor + // Print start up message - ;; Print coloured part of the message - ;; ldy #>startup_message - ;; lda #startup_message + // lda #MEGABASIC\r\r + // MEGABASIC\r\r .byte $12,$05,$4D,$45,$47,$41,$92 .byte $42,$41,$53,$49,$43 .byte $20,$56,$32,$2e,$30,$2e,$30 diff --git a/c64/basic/basic_delete_line.s b/c64/basic/basic_delete_line.s index 4e317f8d..4b4867fd 100644 --- a/c64/basic/basic_delete_line.s +++ b/c64/basic/basic_delete_line.s @@ -1,18 +1,19 @@ - ;; Delete the current BASIC line, which is assumed to have already - ;; been found with basic_find_line. - ;; Really only consists of copying memory down. - ;; The only complication is that we have to do the copy with ROMs - ;; banked out. Oh, yes, and we have to update all the links in - ;; the following basic lines. +// Delete the current BASIC line, which is assumed to have already +// been found with basic_find_line. +// Really only consists of copying memory down. +// The only complication is that we have to do the copy with ROMs +// banked out. Oh, yes, and we have to update all the links in +// the following basic lines. + basic_delete_line: - ;; jsr printf - ;; .byte "DELETING LINE AT $" - ;; .byte $f1,basic_current_line_ptr - ;; .byte $f0,basic_current_line_ptr - ;; .byte $0d,0 + // jsr printf + // .text "DELETING LINE AT $" + // .byte $f1,basic_current_line_ptr + // .byte $f0,basic_current_line_ptr + // .byte $0d,0 - ;; Get address of next line + // Get address of next line ldx #tokenise_work4 - ;; .byte $f0,tokenise_work3 - ;; .byte $0d,0 + // jsr printf + // .text "LINE LENGTH IS $" + // .byte $f0,tokenise_work4 + // .byte $f0,tokenise_work3 + // .byte $0d,0 lda tokenise_work4 sbc #0 cmp #$00 - beq + - ;; Line length is <0 or >255 bytes. - ;; Either way, things are bad, so abort. + beq !+ + // Line length is <0 or >255 bytes. + // Either way, things are bad, so abort. jmp do_MEMORY_CORRUPT_error -* - ;; Length can now be safely assumed to be in the low - ;; byte only, i.e., stored in tokenise_work3 +!: + // Length can now be safely assumed to be in the low + // byte only, i.e., stored in tokenise_work3 lda tokenise_work3 pha tax - ;; Shuffle everything down + // Shuffle everything down jsr basic_shift_mem_down_and_relink - ;; Now decrease top of BASIC mem + // Now decrease top of BASIC mem pla sta tokenise_work3 lda basic_end_of_text_ptr+0 diff --git a/c64/basic/basic_do_error.s b/c64/basic/basic_do_error.s index 731f99c2..ba31a966 100644 --- a/c64/basic/basic_do_error.s +++ b/c64/basic/basic_do_error.s @@ -1,40 +1,37 @@ - ;; Compute's Mapping the 64 p93 +// Compute's Mapping the 64 p93 basic_do_error: - ;; Save error number + // Save error number txa pha - ;; Print ? at start - lda #$0d + // Print ? at start + lda #$0D jsr JCHROUT - lda #$3f + lda #$3F jsr JCHROUT - ;; Print main part of error message + // Print main part of error message pla tax jsr print_packed_message - ;; Print ERROR at end + // Print ERROR at end lda #$20 jsr JCHROUT ldx #33 jsr print_packed_message - ;; XXX print IN if not in direct mode + // XXX print IN if not in direct mode - ;; XXX print line number if not in direct mode + // XXX print line number if not in direct mode - lda #$0d + lda #$0D jsr JCHROUT - lda #$0d + lda #$0D // XXX do we need this? jsr JCHROUT - ;; Reset stack, and go back to main loop - ldx #$fe + // Reset stack, and go back to main loop + ldx #$FE txs jmp basic_main_loop - - - diff --git a/c64/basic/basic_execute_line.s b/c64/basic/basic_execute_line.s index 1ddd7b43..3e92c06c 100644 --- a/c64/basic/basic_execute_line.s +++ b/c64/basic/basic_execute_line.s @@ -1,13 +1,13 @@ - ;; Jump back into the BASIC execute line loop - ;; after first checking that we have a colon - ;; or $00 char +// Jump back into the BASIC execute line loop +// after first checking that we have a colon +// or $00 char basic_end_of_statement_check: ldx #basic_current_line_ptr - ;; .byte $f0,basic_current_line_ptr - ;; .byte ", STATEMENT PTR = $" - ;; .byte $f1,basic_current_statement_ptr - ;; .byte $f0,basic_current_statement_ptr - ;; .byte $d,0 + // jsr printf + // .text "LINE PTR = $" + // .byte $f1,basic_current_line_ptr + // .byte $f0,basic_current_line_ptr + // .text ", STATEMENT PTR = $" + // .byte $f1,basic_current_statement_ptr + // .byte $f0,basic_current_statement_ptr + // .byte $d,0 - ;; Go through the line until its end is reached. - ;; If we reach the end are in direct mode, then - ;; go back to reading input, else look for the - ;; next line, and advance to that, or else - ;; return to READY prompt because we have run out - ;; of program. + // Go through the line until its end is reached. + // If we reach the end are in direct mode, then + // go back to reading input, else look for the + // next line, and advance to that, or else + // return to READY prompt because we have run out + // of program. - ;; Get next char of program text, even if it is hiding under a ROM or the - ;; IO area. + // Get next char of program text, even if it is hiding under a ROM or the + // IO area. ldx #basic_current_line_ptr - ;; .byte $f0,basic_current_line_ptr - ;; .byte $0d,0 + // jsr printf + // .text "INSERTING LINE AT $" + // .byte $f1,basic_current_line_ptr + // .byte $f0,basic_current_line_ptr + // .byte $0d,0 lda basic_current_line_ptr+0 pha @@ -27,20 +28,20 @@ basic_insert_line: pha - ;; Get number of bytes in tokenised line after line number + // Get number of bytes in tokenised line after line number lda tokenise_work2 sec sbc tokenise_work1 - ;; Add on the four bytes space we need + // Add on the four bytes space we need clc adc #5 pha tax - ;; Make the space + // Make the space jsr basic_shift_mem_up_and_relink - ;; Now increase top of BASIC mem + // Now increase top of BASIC mem pla clc adc basic_end_of_text_ptr+0 @@ -49,13 +50,13 @@ basic_insert_line: adc #0 sta basic_end_of_text_ptr+1 - ;; Get pointer back + // Get pointer back pla sta basic_current_line_ptr+1 pla sta basic_current_line_ptr+0 - ;; Write the line number + // Write the line number ldy #2 ldx #$0200 @@ -86,67 +86,66 @@ rsl_l1: lda $0200,x jsr basic_parse_line_number - ;; Get pointer to next char + // Get pointer to next char lda basic_current_statement_ptr+0 sta tokenise_work1 - ;; Got a valid line number -- so do add/del line + // Got a valid line number -- so do add/del line - ;; Skip any spaces after the line number + // Skip any spaces after the line number ldx tokenise_work1 skip_spaces: lda $0200,x cmp #$20 - bne + + bne !+ inx bne skip_spaces -* stx tokenise_work1 +!: stx tokenise_work1 - ;; First, clear all variables, so that we only have to shove BASIC text around. - ;; (We could later remove this requirement, and the only effect should be - ;; to slow things down, and that you might have to either CLR if there is no - ;; memory free, or else it would auto CLR when you ran out of program space). + // First, clear all variables, so that we only have to shove BASIC text around. + // (We could later remove this requirement, and the only effect should be + // to slow things down, and that you might have to either CLR if there is no + // memory free, or else it would auto CLR when you ran out of program space). jsr basic_do_clr - ;; Delete line if present + // Delete line if present jsr basic_find_line - bcs + + bcs !+ - ;; Delete the line, whether we are deleting or - ;; replacing the line + // Delete the line, whether we are deleting or + // replacing the line jsr basic_delete_line -* - ;; Insert new line if non-zero length, i.e., that - ;; we are not just deleting the line. +!: + // Insert new line if non-zero length, i.e., that + // we are not just deleting the line. lda tokenise_work1 cmp tokenise_work2 - beq + + beq !+ jsr basic_insert_line -* - ;; No READY message after entering or deleting a line of BASIC +!: + // No READY message after entering or deleting a line of BASIC jmp basic_read_next_line not_a_line: - ;; Actually interpret the line + // Actually interpret the line - ;; Setup pointer to the statement + // Setup pointer to the statement lda #<$0200 sta basic_current_statement_ptr+0 lda #>$0200 sta basic_current_statement_ptr+1 - ;; There is no stored line, so zero that pointer out + // There is no stored line, so zero that pointer out lda #$00 sta basic_current_line_ptr+0 sta basic_current_line_ptr+1 - ;; Put invalid line number in current line number value, - ;; so that we know we are in direct mode - ;; (Compute's Mapping the 64 p19) + // Put invalid line number in current line number value, + // so that we know we are in direct mode + // (Compute's Mapping the 64 p19) lda #$ff sta basic_current_line_number+1 jmp basic_execute_statement - diff --git a/c64/basic/basic_parse_line_number.s b/c64/basic/basic_parse_line_number.s index 50991ff3..90aa8336 100644 --- a/c64/basic/basic_parse_line_number.s +++ b/c64/basic/basic_parse_line_number.s @@ -3,22 +3,22 @@ basic_parse_line_number: jsr injest_number - ;; Check if the number is a valid line number - ;; i.e., 16 bits, no exponent, no decimal + // Check if the number is a valid line number + // i.e., 16 bits, no exponent, no decimal lda basic_fac1_mantissa+2 ora basic_fac1_mantissa+3 ora basic_fac1_exponent - beq + + beq !+ ml_bad_line_number: - ;; Invalid line number + // Invalid line number jmp do_ILLEGAL_QUANTITY_error -* - ;; Line number are not allowed to have decimal points in them +!: + // Line number are not allowed to have decimal points in them lda tokenise_work4 - cmp #$ff + cmp #$FF bne ml_bad_line_number - ;; Got a valid line number. + // Got a valid line number. lda basic_fac1_mantissa+0 sta basic_line_number+0 lda basic_fac1_mantissa+1 diff --git a/c64/basic/basic_shift_mem_down.s b/c64/basic/basic_shift_mem_down.s index e866828b..dce24825 100644 --- a/c64/basic/basic_shift_mem_down.s +++ b/c64/basic/basic_shift_mem_down.s @@ -1,16 +1,16 @@ basic_shift_mem_down_and_relink: - ;; Shift memory down to basic_current_line_pointer - ;; from X bytes further along. + // Shift memory down to basic_current_line_pointer + // from X bytes further along. - ;; Destination is basic_current_line_ptr + // Destination is basic_current_line_ptr lda basic_current_line_ptr+0 sta memmove_dst+0 lda basic_current_line_ptr+1 sta memmove_dst+1 - ;; Source is that plus X + // Source is that plus X txa - pha ; also keep for later + pha // also keep for later clc adc basic_current_line_ptr+0 sta memmove_src+0 @@ -18,7 +18,7 @@ basic_shift_mem_down_and_relink: adc #0 sta memmove_src+1 - ;; Size is distance from source to end of BASIC text. + // Size is distance from source to end of BASIC text. lda basic_end_of_text_ptr+0 sec sbc memmove_src+0 @@ -27,32 +27,32 @@ basic_shift_mem_down_and_relink: sbc memmove_src+1 sta memmove_size+1 - ;; jsr printf - ;; .byte "TOP OF BASIC = $" - ;; .byte $f1,basic_end_of_text_ptr - ;; .byte $f0,basic_end_of_text_ptr - ;; .byte $0d - ;; .byte "SHIFTING DOWN $" - ;; .byte $f1,memmove_size - ;; .byte $f0,memmove_size - ;; .byte " BYTES FROM $" - ;; .byte $f1,memmove_src - ;; .byte $f0,memmove_src - ;; .byte " TO $" - ;; .byte $f1,memmove_dst - ;; .byte $f0,memmove_dst - ;; .byte $0d,0 + // jsr printf + // .text "TOP OF BASIC = $" + // .byte $f1,basic_end_of_text_ptr + // .byte $f0,basic_end_of_text_ptr + // .byte $0d + // .text "SHIFTING DOWN $" + // .byte $f1,memmove_size + // .byte $f0,memmove_size + // .text " BYTES FROM $" + // .byte $f1,memmove_src + // .byte $f0,memmove_src + // .text " TO $" + // .byte $f1,memmove_dst + // .byte $f0,memmove_dst + // .byte $0d,0 - ;; The copy routine that copies under the ROMs is as simple - ;; as possible to be as small as possible, so we have - ;; to adjust the pointers and counts so that the simple - ;; increment and decrement bounds checks work. + // The copy routine that copies under the ROMs is as simple + // as possible to be as small as possible, so we have + // to adjust the pointers and counts so that the simple + // increment and decrement bounds checks work. - ;; Specifically we want Y pre-set so that the end of the - ;; copy ends when Y = $00. - ;; So if copying 1 byte, we want Y=$FF - ;; This means we have to then reduce the source and - ;; target pointers by the same amount + // Specifically we want Y pre-set so that the end of the + // copy ends when Y = $00. + // So if copying 1 byte, we want Y=$FF + // This means we have to then reduce the source and + // target pointers by the same amount lda memmove_size+0 eor #$ff @@ -75,50 +75,50 @@ basic_shift_mem_down_and_relink: sbc #0 sta memmove_dst+1 - ;; Increase copy page count so we can post-decrement compare with $00 + // Increase copy page count so we can post-decrement compare with $00 inc memmove_size+1 - ;; jsr printf - ;; .byte "REVISED BOUNDS $" - ;; .byte $f1,memmove_size - ;; .byte $f0,memmove_size - ;; .byte " BYTES FROM $" - ;; .byte $f1,memmove_src - ;; .byte $f0,memmove_src - ;; .byte " TO $" - ;; .byte $f1,memmove_dst - ;; .byte $f0,memmove_dst - ;; .byte $0d,0 + // jsr printf + // .text "REVISED BOUNDS $" + // .byte $f1,memmove_size + // .byte $f0,memmove_size + // .text " BYTES FROM $" + // .byte $f1,memmove_src + // .byte $f0,memmove_src + // .text " TO $" + // .byte $f1,memmove_dst + // .byte $f0,memmove_dst + // .byte $0d,0 - ;; Get Y value ready for the copy + // Get Y value ready for the copy ldy memmove_size+0 jsr shift_mem_down - ;; Get length of deletion back + // Get length of deletion back pla sta tokenise_work3 - ;; Check if we still have any lines left + // Check if we still have any lines left ldy #0 ldx #basic_end_of_text_ptr - ;; .byte $f0,basic_end_of_text_ptr - ;; .byte $0d - ;; .byte "SHIFTING UP $" - ;; .byte $f1,memmove_size - ;; .byte $f0,memmove_size - ;; .byte " BYTES FROM $" - ;; .byte $f1,memmove_src - ;; .byte $f0,memmove_src - ;; .byte " TO $" - ;; .byte $f1,memmove_dst - ;; .byte $f0,memmove_dst - ;; .byte $0d,0 + // jsr printf + // .text "TOP OF BASIC = $" + // .byte $f1,basic_end_of_text_ptr + // .byte $f0,basic_end_of_text_ptr + // .byte $0d + // .text "SHIFTING UP $" + // .byte $f1,memmove_size + // .byte $f0,memmove_size + // .text " BYTES FROM $" + // .byte $f1,memmove_src + // .byte $f0,memmove_src + // .text " TO $" + // .byte $f1,memmove_dst + // .byte $f0,memmove_dst + // .byte $0d,0 - ;; To make life simple for the copy routine that lives in RAM, - ;; we have to adjust the end pointers down one page and set Y to the low - ;; byte of the copy size. + // To make life simple for the copy routine that lives in RAM, + // we have to adjust the end pointers down one page and set Y to the low + // byte of the copy size. lda memmove_src+0 sec sbc memmove_size+0 @@ -75,35 +75,35 @@ basic_shift_mem_up_and_relink: sbc #0 sta memmove_dst+1 - ;; Now make exit easy, by being able to check for zero on size high byte when done + // Now make exit easy, by being able to check for zero on size high byte when done inc memmove_size+1 - ;; Then set Y to the number offset required + // Then set Y to the number offset required ldy memmove_size+0 iny stx tokenise_work3 - ;; jsr printf - ;; .byte "REVISED BOUNDS $" - ;; .byte $f1,memmove_size - ;; .byte $f0,memmove_size - ;; .byte " BYTES FROM $" - ;; .byte $f1,memmove_src - ;; .byte $f0,memmove_src - ;; .byte " TO $" - ;; .byte $f1,memmove_dst - ;; .byte $f0,memmove_dst - ;; .byte $0d,0 + // jsr printf + // .text "REVISED BOUNDS $" + // .byte $f1,memmove_size + // .byte $f0,memmove_size + // .text " BYTES FROM $" + // .byte $f1,memmove_src + // .byte $f0,memmove_src + // .text " TO $" + // .byte $f1,memmove_dst + // .byte $f0,memmove_dst + // .byte $0d,0 - ;; Do the copy + // Do the copy jsr shift_mem_up - ;; Now fix the pointer to the next line + // Now fix the pointer to the next line - ;; First, we need to point the current BASIC line - ;; pointer to itself, so that we can add the shift - ;; to make it end up pointing to the next line + // First, we need to point the current BASIC line + // pointer to itself, so that we can add the shift + // to make it end up pointing to the next line ldy #0 ldx #basic_end_of_text_ptr - ;; .byte $f0,basic_end_of_text_ptr - ;; .byte $d," BEFORE = $" - ;; .byte $f1,memmove_dst - ;; .byte $f0,memmove_dst - ;; .byte ", AFTER = $" - ;; .byte $f1,memmove_src - ;; .byte $f0,memmove_src - ;; .byte $d - ;; .byte 0 + // jsr printf + // .text "LINE ADDR = $" + // .byte $f1,basic_end_of_text_ptr + // .byte $f0,basic_end_of_text_ptr + // .text $d," BEFORE = $" + // .byte $f1,memmove_dst + // .byte $f0,memmove_dst + // .text ", AFTER = $" + // .byte $f1,memmove_src + // .byte $f0,memmove_src + // .byte $d + // .byte 0 - ;; Write memmove_src back to current line pointer + // Write memmove_src back to current line pointer ldy #0 ldx #packed_keywords sta temp_string_ptr+1 - ;; Subtract $80 from token to get offset in word - ;; list + // Subtract $80 from token to get offset in word + // list txa and #$7f tax - ;; Now ask for it to be printed + // Now ask for it to be printed ldy #$ff jsr packed_word_search @@ -100,11 +100,11 @@ list_not_quote: cmp #$8f bne list_not_rem - ;; REM command locks quote flag on until the end of the line, allowing - ;; funny characters in REM statements without problem. + // REM command locks quote flag on until the end of the line, allowing + // funny characters in REM statements without problem. inc $0427 - sta quote_mode_flag ; Any value other than $00 or $FF will lock quote mode on, so the token value of REM is fine here - ;; FALL THROUGH + sta quote_mode_flag // Any value other than $00 or $FF will lock quote mode on, so the token value of REM is fine here + // FALL THROUGH list_not_rem: iny @@ -116,10 +116,10 @@ list_is_literal: bne list_print_loop list_end_of_line: - ;; Clear reverse flag + // Clear reverse flag lda #$92 jsr JCHROUT - ;; Print end of line + // Print end of line lda #$0d jsr JCHROUT rts diff --git a/c64/basic/cmd_load.s b/c64/basic/cmd_load.s index bca40cf2..a01a365e 100644 --- a/c64/basic/cmd_load.s +++ b/c64/basic/cmd_load.s @@ -1,64 +1,64 @@ cmd_load: - ;; Parse filename - ;; (we can tell the KERNAL where it is in memory directly, since the - ;; KERNAL will be able to peek under ROMs to read it, since it will have - ;; to be able to peek under the ROMs for SAVE and VERIFY). - ;; Parse optional device # - ;; Parse optional secondary address + // Parse filename + // (we can tell the KERNAL where it is in memory directly, since the + // KERNAL will be able to peek under ROMs to read it, since it will have + // to be able to peek under the ROMs for SAVE and VERIFY). + // Parse optional device # + // Parse optional secondary address - ;; XXX - C64 BASIC apparently doesn't clear variables after a LOAD in the - ;; middle of a program. For safety, we do. + // XXX - C64 BASIC apparently doesn't clear variables after a LOAD in the + // middle of a program. For safety, we do. jsr basic_do_clr - ;; Setup Kernal to print control messages or not - lda #$80 ; display control messages and omit error messages + // Setup Kernal to print control messages or not + lda #$80 // display control messages and omit error messages ldx basic_current_line_number+1 cpx #$FF - beq + - lda #$00 ; direct mode - don't display anything -* + beq !+ + lda #$00 // direct mode - don't display anything +!: jsr JSETMSG - ;; Set filename and length + // Set filename and length lda #$00 sta FNLEN - ;; Without tape support, LOAD must have a filename - ;; (This also skips any leading spaces) + // Without tape support, LOAD must have a filename + // (This also skips any leading spaces) jsr basic_end_of_statement_check - bcc + + bcc !+ jmp do_MISSING_FILENAME_error -* +!: jsr basic_fetch_and_consume_character cmp #$22 - beq + - jmp do_SYNTAX_ERROR -* - ;; Filename starts here so set pointer + beq !+ + jmp do_SYNTAX_error +!: + // Filename starts here so set pointer lda basic_current_statement_ptr+0 sta current_filename_ptr+0 lda basic_current_statement_ptr+1 sta current_filename_ptr+1 - ;; Now search for end of line or closing quote - ;; so that we know the length of the filename + // Now search for end of line or closing quote + // so that we know the length of the filename getting_filename: jsr basic_fetch_and_consume_character cmp #$22 beq got_filename cmp #$00 - bne + + bne !+ jsr basic_unconsume_character jmp got_filename -* +!: inc FNLEN jmp getting_filename got_filename: - ;; Now fetch the file number, start from the default one + // Now fetch the file number, start from the default one jsr select_device stx current_device_number jsr injest_comma @@ -66,116 +66,116 @@ got_filename: jsr basic_parse_line_number lda basic_line_number+1 - beq + + beq !+ jmp do_ILLEGAL_QUANTITY_error -* +!: lda basic_line_number+0 sta current_device_number got_devicenumber: - ;; Now fetch the secondary address + // Now fetch the secondary address lda #$00 sta current_secondary_address jsr injest_comma bcs got_secondaryaddress jsr basic_parse_line_number lda basic_line_number+1 - bne + + bne !+ lda basic_line_number+0 sta current_secondary_address jmp got_secondaryaddress -* - ;; Second parameter is above 255, this can't be a secondary address - ;; Use it as load address instead - ;; XXX temporary syntax, it would be better to use something - ;; XXX like 'LOAD"FILE",8 TO 49152' +!: + // Second parameter is above 255, this can't be a secondary address + // Use it as load address instead + // XXX temporary syntax, it would be better to use something + // XXX like 'LOAD"FILE",8 TO 49152' ldx basic_line_number+0 ldy basic_line_number+1 bne got_loadaddress got_secondaryaddress: - ldx #<$0801 + ldx #<$0801 // XXX use start text vector ldy #>$0801 got_loadaddress: - lda #$00 ; LOAD not verify + lda #$00 // LOAD not verify jsr via_ILOAD - bcc + + bcc !+ - ;; A = KERNAL error code, which also almost match - ;; basic ERROR codes, so we can just copy the - ;; error code to X, decrement, and handle normally + // A = KERNAL error code, which also almost match + // basic ERROR codes, so we can just copy the + // error code to X, decrement, and handle normally tax dex jmp do_basic_error -* - ;; $YYXX is the last loaded address, so store it +!: + // $YYXX is the last loaded address, so store it stx basic_end_of_text_ptr+0 sty basic_end_of_text_ptr+1 - ;; Now relink the loaded program, as we cannot trust the line - ;; links supplied. For example, the VICE virtual drive emulation - ;; always supplies $0101 as the address of the next line. + // Now relink the loaded program, as we cannot trust the line + // links supplied. For example, the VICE virtual drive emulation + // always supplies $0101 as the address of the next line. jsr basic_relink_program - ;; After LOADing, we either start the program from the beginning, - ;; or go back to the READY prompt if LOAD was called from direct mode. + // After LOADing, we either start the program from the beginning, + // or go back to the READY prompt if LOAD was called from direct mode. - ;; Reset to start of program + // Reset to start of program lda basic_start_of_text_ptr+0 sta basic_current_line_ptr+0 lda basic_start_of_text_ptr+1 sta basic_current_line_ptr+1 - ;; XXX - should run program if LOAD was used in program mode + // XXX - should run program if LOAD was used in program mode jmp basic_main_loop basic_relink_program: - ;; Start by getting pointer to the first line + // Start by getting pointer to the first line lda basic_start_of_text_ptr+0 sta basic_current_line_ptr+0 lda basic_start_of_text_ptr+1 sta basic_current_line_ptr+1 basic_relink_loop: - ;; Is the pointer to the end of the program + // Is the pointer to the end of the program ldy #1 ldx #$0801 @@ -22,8 +22,8 @@ basic_do_new: lda #<$0803 sta basic_start_of_vars_ptr+0 - ;; Zero line pointer - ;; XXX - We should also zero $0800, i.e., basic_start_of_text_ptr - 1 + // Zero line pointer + // XXX - We should also zero $0800, i.e., basic_start_of_text_ptr - 1 ldy #$00 tya sta (basic_start_of_text_ptr),y @@ -31,32 +31,32 @@ basic_do_new: sta (basic_start_of_text_ptr),y - ;; Get top of memory. - ;; If a cart is present, then it is $7FFF, - ;; if not, then it is $F7FF, since we support having - ;; programs and variables under ROM. - ;; i.e., we support 56KB RAM for BASIC, keeping some space - ;; free for some optimisation structures, e.g., FOR/NEXT loop - ;; records (without them going on the stack), GOSUB stack - ;; (same story), expression value cache? + // Get top of memory. + // If a cart is present, then it is $7FFF, + // if not, then it is $F7FF, since we support having + // programs and variables under ROM. + // i.e., we support 56KB RAM for BASIC, keeping some space + // free for some optimisation structures, e.g., FOR/NEXT loop + // records (without them going on the stack), GOSUB stack + // (same story), expression value cache? - sec ; Read, not write value + sec // Read, not write value jsr JMEMTOP cpx #$80 - beq + + beq !+ lda #>$f7ff - .byte $2c -* lda #>$7FFF + .byte $2C +!: lda #>$7FFF sta basic_top_of_memory_ptr+1 sta basic_start_of_strings_ptr+1 lda #<$f7ff sta basic_top_of_memory_ptr+0 sta basic_start_of_strings_ptr+0 - ;; FALL THROUGH + // FALL THROUGH basic_do_clr: - ;; Clear variables, arrays and strings + // Clear variables, arrays and strings lda basic_start_of_vars_ptr+0 sta basic_start_of_arrays_ptr+0 sta basic_start_of_free_space_ptr+0 @@ -65,5 +65,3 @@ basic_do_clr: sta basic_start_of_free_space_ptr+1 rts - - diff --git a/c64/basic/cmd_rem.s b/c64/basic/cmd_rem.s index d529c8ee..24af2e0b 100644 --- a/c64/basic/cmd_rem.s +++ b/c64/basic/cmd_rem.s @@ -1,4 +1,4 @@ - ;; REM statement just skips to the next line +// REM statement just skips to the next line cmd_rem: jmp basic_end_of_line diff --git a/c64/basic/cmd_run.s b/c64/basic/cmd_run.s index 6823ea86..83b3c12c 100644 --- a/c64/basic/cmd_run.s +++ b/c64/basic/cmd_run.s @@ -1,21 +1,21 @@ cmd_run: - ;; RUN clears all variables + // RUN clears all variables jsr basic_do_clr cmd_goto: - ;; Reset line pointer to first line of program. + // Reset line pointer to first line of program. lda basic_start_of_text_ptr+0 sta basic_current_line_ptr+0 lda basic_start_of_text_ptr+1 sta basic_current_line_ptr+1 jsr basic_end_of_statement_check - bcs + + bcs !+ jsr basic_parse_line_number jsr basic_find_line - bcc + - ;; Line doesn't exist, so report error + bcc !+ + // Line doesn't exist, so report error jmp do_UNDEFD_STATEMENT_error -* - ;; Run it! +!: + // Run it! jmp basic_execute_from_current_line diff --git a/c64/basic/cmd_sys.s b/c64/basic/cmd_sys.s index 2328a0a4..2ca529d0 100644 --- a/c64/basic/cmd_sys.s +++ b/c64/basic/cmd_sys.s @@ -1,23 +1,23 @@ cmd_sys: jsr basic_end_of_statement_check - bcc + + bcc !+ - ;; SYS requires an argument - jmp do_SYNTAX_ERROR + // SYS requires an argument + jmp do_SYNTAX_error -* +!: jsr basic_parse_line_number - ;; setup call - lda #$4C ;JMP + // setup call + lda #$4C // JMP opcode sta USRPOK lda basic_line_number+0 sta USRADD+0 lda basic_line_number+1 sta USRADD+1 - ;; Setup the register values + // Setup the register values lda SPREG pha ldy SYREG @@ -25,7 +25,7 @@ cmd_sys: lda SAREG plp - ;; Call the routine. + // Call the routine. jsr USRPOK jmp basic_execute_statement diff --git a/c64/basic/cmd_unimplemented.s b/c64/basic/cmd_unimplemented.s index 018cc294..67ec4811 100644 --- a/c64/basic/cmd_unimplemented.s +++ b/c64/basic/cmd_unimplemented.s @@ -1,4 +1,4 @@ - ;; Default handler for all not-yet-implemented commands +// Default handler for all not-yet-implemented commands cmd_for: cmd_next: @@ -13,7 +13,7 @@ cmd_restore: cmd_gosub: cmd_return: - ;; $90-$9F + // $90-$9F cmd_on: cmd_wait: cmd_save: @@ -26,7 +26,7 @@ cmd_cont: cmd_cmd: cmd_open: - ;; $A0-$AF + // $A0-$AF cmd_close: cmd_get: cmd_tab: @@ -43,7 +43,7 @@ cmd_div: cmd_exponent: cmd_and: - ;; $B0-$BF + // $B0-$BF cmd_or: cmd_greater: cmd_equal: @@ -61,7 +61,7 @@ cmd_exp: cmd_cos: cmd_sin: - ;; $C0-$CF + // $C0-$CF cmd_tan: cmd_atn: cmd_peek: @@ -73,10 +73,10 @@ cmd_chr: cmd_left: cmd_right: cmd_mid: -cmd_go: - ;; Undefined tokens +cmd_go: + + // Undefined tokens cmd_unimplemented: - - + jmp do_NOT_IMPLEMENTED_error diff --git a/c64/basic/do_basic_error.s b/c64/basic/do_basic_error.s index f466f79d..e41822bf 100644 --- a/c64/basic/do_basic_error.s +++ b/c64/basic/do_basic_error.s @@ -1,48 +1,48 @@ - ;; As many errors are triggered from many places in the BASIC - ;; interprettor, it is important to have an efficicent means of - ;; calling them. - ;; LDX #$nn / jmp do_basic_error - ;; is the simplest, but takes 5 bytes. - ;; Having a direct JMP address for each error is preferable, as - ;; it reduces the overhead to 3 bytes, but at the cost of having - ;; a jump table of some sort. The .byte $2C method can be used - ;; to have a set of addresses that each execute a different - ;; LDX #$nn command, reducing the cost of the jump table to 3 - ;; bytes per error number. - ;; But we can do better with a bit of scullduggery and carnal - ;; knowledge of ZP usage. - ;; The INC $nn opcode is $E6. ZP location $E6 is one of the screen - ;; link addresses. In the original KERNAL, the lower bits of those - ;; addresses have meaning, but in our KERNAL, we ignore them, and just - ;; have them all zeroes. So.... We can have a sequence of $E6 bytes, - ;; and know exactly how many of them have been executed, by checking - ;; the value of $E6. Then all we need to worry about is if an odd - ;; number is required, then we have to have an exit that has a $E6 - ;; opcode with some other address as target, but where the byte value - ;; of that argument can be safely executed as a CPU instruction. - ;; NOP = $EA is the obvious choice, as if used as an argument to - ;; $E6 will increment location $EA, which is another of the screen - ;; link addresses. +// As many errors are triggered from many places in the BASIC +// interprettor, it is important to have an efficicent means of +// calling them. +// LDX #$nn / jmp do_basic_error +// is the simplest, but takes 5 bytes. +// Having a direct JMP address for each error is preferable, as +// it reduces the overhead to 3 bytes, but at the cost of having +// a jump table of some sort. The .byte $2C method can be used +// to have a set of addresses that each execute a different +// LDX #$nn command, reducing the cost of the jump table to 3 +// bytes per error number. +// But we can do better with a bit of scullduggery and carnal +// knowledge of ZP usage. +// The INC $nn opcode is $E6. ZP location $E6 is one of the screen +// link addresses. In the original KERNAL, the lower bits of those +// addresses have meaning, but in our KERNAL, we ignore them, and just +// have them all zeroes. So.... We can have a sequence of $E6 bytes, +// and know exactly how many of them have been executed, by checking +// the value of $E6. Then all we need to worry about is if an odd +// number is required, then we have to have an exit that has a $E6 +// opcode with some other address as target, but where the byte value +// of that argument can be safely executed as a CPU instruction. +// NOP = $EA is the obvious choice, as if used as an argument to +// $E6 will increment location $EA, which is another of the screen +// link addresses. - ;; This gives a total overhead of 18 bytes + 1 byte per error - ;; message. This compares favourably to the 3 bytes per error - ;; message that the $2C method would result in. +// This gives a total overhead of 18 bytes + 1 byte per error +// message. This compares favourably to the 3 bytes per error +// message that the $2C method would result in. do_NOT_IMPLEMENTED_error: .byte $E6 do_MEMORY_CORRUPT_error: .byte $E6 - ;; the message "BYTES FREE" + // the message "BYTES FREE" .byte $E6 - ;; the word ERROR + // the word ERROR .byte $E6 - ;; The word "SAVING" + // The word "SAVING" .byte $E6 - ;; The word "VERIFYING" + // The word "VERIFYING" .byte $E6 - ;; The word "LOADING" + // The word "LOADING" .byte $E6 - ;; The word "READY." + // The word "READY." .byte $E6 do_LOAD_error: .byte $E6 @@ -103,69 +103,70 @@ do_FILE_OPEN_error: do_TO_MANY_FILES_error: .byte $EA - ;; Now get the error # and restore $E6 to its correct value + // Now get the error # and restore $E6 to its correct value lda $E6 pha and #$80 sta $E6 pla - ;; $E6 has even part + // $E6 has even part asl ora $EA and #$7f tax - ;; Restore $EA to correct value in case the NOP above is used - ;; as an argument to the preceeding INC $nn (opcode $E6). - LDA $EA + // Restore $EA to correct value in case the NOP above is used + // as an argument to the preceeding INC $nn (opcode $E6). + lda $EA and #$80 sta $EA - ;; FALL THROUGH + // FALL THROUGH - ;; Error # in X + // Error # in X do_basic_error: - ;; "?" + // "?" txa pha lda #$0d - jsr $ffd2 + jsr JCHROUT lda #$3f - jsr $ffd2 + jsr JCHROUT pla tax - ;; Error message text + // Error message text jsr print_packed_message - ;; A space between error name and word error + // A space between error name and word error lda #$20 jsr $ffd2 - ;; "ERROR" + // "ERROR" ldx #33 jsr print_packed_message lda basic_current_line_number+1 cmp #$ff - beq + + beq !+ - ;; We were in a program, so show IN - jsr printf - .byte " IN ",0 + // We were in a program, so show IN + jsr printf // XXX don't use printf, use packed messages + .text " IN " + .byte 0 lda basic_current_line_number+1 ldx basic_current_line_number+0 jsr print_integer -* - ;; New lines +!: + // New lines lda #$0d jsr $ffd2 lda #$00 jsr $ffd2 - ;; XXX - Restore stack depth first? + // XXX - Restore stack depth first? jmp basic_main_loop diff --git a/c64/basic/fac1_mul.s b/c64/basic/fac1_mul.s index 0b559669..f3618aa6 100644 --- a/c64/basic/fac1_mul.s +++ b/c64/basic/fac1_mul.s @@ -1,23 +1,23 @@ - ;; Multiply Floating Point Accumulator by 10 - ;; = 8x + 2x - ;; Implement by shifting MAC left one bit, - ;; and then keeping that value to add on after - ;; shifting two more bits left. - ;; This should be done using basic_fac1_overflow to - ;; hold the overflow bits, so that the result can - ;; be exponent adjusted after, if required. +// Multiply Floating Point Accumulator by 10 +// = 8x + 2x +// Implement by shifting MAC left one bit, +// and then keeping that value to add on after +// shifting two more bits left. +// This should be done using basic_fac1_overflow to +// hold the overflow bits, so that the result can +// be exponent adjusted after, if required. fac1_mul10: lda #$00 sta basic_fac1_overflow - ;; Multiply mantissa by 2 + // Multiply mantissa by 2 jsr fac1_mantissa_mul2 - ;; copy down to BASIC numeric work area at $57 - ;; (basic_numeric_work_area) - ;; (We copy all 7 bytes off the FAC1, so that we have - ;; the overflow bits, and the copy is as small as possible) + // copy down to BASIC numeric work area at $57 + // (basic_numeric_work_area) + // (We copy all 7 bytes off the FAC1, so that we have + // the overflow bits, and the copy is as small as possible) ldx #7 f1m10_l1: lda basic_fac1_mantissa,x @@ -25,11 +25,11 @@ f1m10_l1: dex bpl f1m10_l1 - ;; Multiply mantissa by 4, so it is now 8x original + // Multiply mantissa by 4, so it is now 8x original jsr fac1_mantissa_mul2 jsr fac1_mantissa_mul2 - ;; Now add stored value of 2x to it, to get the total x10 + // Now add stored value of 2x to it, to get the total x10 ldy #3 ldx #0 clc @@ -44,22 +44,22 @@ f1m10_l2: adc basic_numeric_work_area+7 sta basic_fac1_overflow - ;; Now shift right and increase exponent until overflow - ;; bits = $00 + // Now shift right and increase exponent until overflow + // bits = $00 f1m10_l3: lda basic_fac1_overflow - bne + - ;; All done, return + bne !+ + // All done, return clc rts -* - ;; Divide mantissa by two, and increment exponent +!: + // Divide mantissa by two, and increment exponent jsr fac1_mantissa_div2 inc basic_fac1_exponent lda basic_fac1_exponent bpl f1m10_l3 - ;; Exponent has bit 7 set, so has wrapped. - ;; = OVERFLOW ERROR + // Exponent has bit 7 set, so has wrapped. + // = OVERFLOW ERROR jmp do_OVERFLOW_error fac1_mantissa_mul2: @@ -67,8 +67,8 @@ fac1_mantissa_mul2: ldx #0 clc f1m1_l1: - ;; Multiply mantissa by 2, and store overflow - ;; in basic_fac1_bits + // Multiply mantissa by 2, and store overflow + // in basic_fac1_bits lda basic_fac1_mantissa,x rol sta basic_fac1_mantissa,x @@ -82,7 +82,7 @@ f1m1_l1: rts fac1_mantissa_div2: - ;; Divide mantissa by 2, including using overflow bits + // Divide mantissa by 2, including using overflow bits clc lda basic_fac1_overflow ror diff --git a/c64/basic/injest_comma.s b/c64/basic/injest_comma.s index 43be5113..06e50338 100644 --- a/c64/basic/injest_comma.s +++ b/c64/basic/injest_comma.s @@ -1,15 +1,15 @@ -;; Consummes a comma in a BASIC code, C set for no coma found +// Consummes a comma in a BASIC code, C set for no coma found injest_comma: jsr basic_fetch_and_consume_character - cmp #$2C ; comma character + cmp #$2C // comma character beq injest_comma_found - cmp #$20 - beq injest_comma ; space, can always be skipped + cmp #$20 // space, can always be skipped + beq injest_comma - ;; not found + // not found jsr basic_unconsume_character sec rts @@ -17,4 +17,3 @@ injest_comma: injest_comma_found: clc rts - diff --git a/c64/basic/injest_number.s b/c64/basic/injest_number.s index 50b4203d..948ddc82 100644 --- a/c64/basic/injest_number.s +++ b/c64/basic/injest_number.s @@ -1,37 +1,37 @@ - ;; Parse a number from the input buffer at (basic_current_statement_ptr) - ;; Result is put into FAC1. - ;; basic_current_statement_ptr is updated with first position after the number. +// Parse a number from the input buffer at (basic_current_statement_ptr) +// Result is put into FAC1. +// basic_current_statement_ptr is updated with first position after the number. - ;; XXX - Remember decimal position and exponent, and apply them - ;; after to produce normalised floating point number. +// XXX - Remember decimal position and exponent, and apply them +// after to produce normalised floating point number. - ;; XXX - Doesn't use routines to access memory under ROMs etc. - ;; This is important, because this routine operates on numbers in BASIC text. +// XXX - Doesn't use routines to access memory under ROMs etc. +// This is important, because this routine operates on numbers in BASIC text. ij_not_a_digit: - ;; XXX check for "." or "E" - ;; Other chars terminate the accumulation. + // XXX check for "." or "E" + // Other chars terminate the accumulation. - ;; Look for exponentiation marker - ;; XXX - Implement me! - ;; Probably should have a flag so that we know if we are accumulating - ;; exponent or mantissa digits + // Look for exponentiation marker + // XXX - Implement me! + // Probably should have a flag so that we know if we are accumulating + // exponent or mantissa digits - ;; Look for decimal point + // Look for decimal point cmp #$2e bne ij_not_decimal lda tokenise_work4 cmp #$ff beq ij_found_decimal - ;; More than one decimal point in a number means we have reached the end of the number + // More than one decimal point in a number means we have reached the end of the number clc rts ij_found_decimal: - ;; Found decimal. - ;; Thus start counting digits after the decimal, so that we - ;; can do the necessary number of divide by 10s on the final - ;; number. + // Found decimal. + // Thus start counting digits after the decimal, so that we + // can do the necessary number of divide by 10s on the final + // number. lda #$00 sta tokenise_work4 @@ -39,31 +39,30 @@ ij_found_decimal: ij_not_decimal: - - CLC - RTS + clc + rts injest_number: - ;; Clear FAC1 + // Clear FAC1 jsr erase_fac1 - ;; Clear decimal position flag + // Clear decimal position flag lda #$ff sta tokenise_work4 - ;; Check if leading char is a - sign - ;; Note: the - will have been tokenised to $AB - ;; XXX - implement + // Check if leading char is a - sign + // Note: the - will have been tokenised to $AB + // XXX - implement ldy #$00 lda (basic_current_statement_ptr),y cmp #$AB bne ij_not_minus - ;; Set sign to negative + // Set sign to negative lda #$ff sta basic_fac1_sign - ;; Skip over the minus sign + // Skip over the minus sign jsr basic_consume_character ij_not_minus: @@ -77,43 +76,43 @@ ij_loop1: cmp #$3a bcs ij_not_a_digit - ;; It is a digit + // It is a digit - ;; Only add digit if we have not overflowed the accuracy of - ;; the mantissa + // Only add digit if we have not overflowed the accuracy of + // the mantissa lda basic_fac1_exponent beq ij_accept_precision - ;; We have an extra digit after saturating our precision. - ;; Thus we should ignore the digit, and just multiply the FAC - ;; by 10, but only if we have not seen a decimal point. - ;; If we have seen a decimal point, then we can completely ignore - ;; the digit, as it is contributing not recordable information + // We have an extra digit after saturating our precision. + // Thus we should ignore the digit, and just multiply the FAC + // by 10, but only if we have not seen a decimal point. + // If we have seen a decimal point, then we can completely ignore + // the digit, as it is contributing not recordable information lda tokenise_work4 cmp #$ff bne ij_seen_decimal_point jsr fac1_mul10 - ;; Fall through + // Fall through ij_seen_decimal_point: jmp ij_consider_next_digit ij_accept_precision: - ;; We can accept more precision, so multiply the mantissa by 10, so that - ;; we can add the new digit in + // We can accept more precision, so multiply the mantissa by 10, so that + // we can add the new digit in jsr fac1_mul10 lda basic_fac1_exponent bne ij_consider_next_digit - ;; Get digit + // Get digit ldy #$00 lda (basic_current_statement_ptr),y sec sbc #$30 - ;; Add to FAC1 mantissa + // Add to FAC1 mantissa clc adc basic_fac1_mantissa+0 sta basic_fac1_mantissa+0 @@ -127,16 +126,16 @@ ij_loop2: dey bne ij_loop2 - bcc + - ;; Carry set, so we have overflowed. - ;; We should shift everything right one digit, and increase - ;; the exponent by one. The non-zero exponent tells us that we - ;; can't fit any more precision in. + bcc !+ + // Carry set, so we have overflowed. + // We should shift everything right one digit, and increase + // the exponent by one. The non-zero exponent tells us that we + // can't fit any more precision in. jsr fac1_mantissa_div2 -* +!: ij_consider_next_digit: - ;; Consider next digit + // Consider next digit jsr basic_consume_character jmp ij_loop1 @@ -146,10 +145,10 @@ ij_consider_next_digit: erase_fac1: lda #$00 ldx #8 -* +!: sta basic_fac1_exponent,x dex - bpl - + bpl !- sta basic_fac1_mantissa_lob rts diff --git a/c64/basic/pack_word.s b/c64/basic/pack_word.s index e9e42de1..74eca527 100644 --- a/c64/basic/pack_word.s +++ b/c64/basic/pack_word.s @@ -1,76 +1,77 @@ - ;; Pack a word using the simple compression scheme. - ;; This has to be the same implementation as in compress_text.c - ;; because we compress input lines of BASIC to do the tokenisation. - ;; This allows us to search through the compressed tokens directly - ;; using the compressed fragment of BASIC, and thus work out the - ;; token for a given piece of string. - ;; This also helps ensure that we have an implementation that is totally - ;; different to that of the original C64 BASIC, as well as likely - ;; saving a bit of space in the ROM, especially once we start implementing - ;; larger keyword vocabs for BASIC 7 or BASIC 10 compatibility, since the - ;; compression and decompression machinery is of fixed size. +// Pack a word using the simple compression scheme. +// This has to be the same implementation as in compress_text.c +// because we compress input lines of BASIC to do the tokenisation. +// This allows us to search through the compressed tokens directly +// using the compressed fragment of BASIC, and thus work out the +// token for a given piece of string. +// This also helps ensure that we have an implementation that is totally +// different to that of the original C64 BASIC, as well as likely +// saving a bit of space in the ROM, especially once we start implementing +// larger keyword vocabs for BASIC 7 or BASIC 10 compatibility, since the +// compression and decompression machinery is of fixed size. pack_word: - ;; Inputs: - ;; X = offset of string to pack. Address is $0200 + X - ;; tokenise_work1 = number of bytes to pack - ;; tokenise_work2 = packed length of string + // Inputs: + // X = offset of string to pack. Address is $0200 + X + // tokenise_work1 = number of bytes to pack + // tokenise_work2 = packed length of string - ;; Outputs: - ;; Output is written to $0100 (bottom of stack). + // Outputs: + // Output is written to $0100 (bottom of stack). - ;; Memory modified: - ;; tokenise_work4 = temporary storage - ;; tokenise_work3 = flag for whether we have a nybl prepared or not. - ;; (This can also be checked on exit, to know whether the last byte - ;; is incomplete, which is important for searching for abbreviated - ;; key words.) + // Memory modified: + // tokenise_work4 = temporary storage + // tokenise_work3 = flag for whether we have a nybl prepared or not. + // (This can also be checked on exit, to know whether the last byte + // is incomplete, which is important for searching for abbreviated + // key words.) - ;; Make sure we have a sane request + // Make sure we have a sane request lda tokenise_work1 - bne + + bne !+ sec rts -* - ;; Initialise internal variables +!: + // Initialise internal variables lda #$00 sta tokenise_work2 sta tokenise_work3 pack_char_loop: - ;; Get the next char + // Get the next char lda $0200,x - ;; Work out what type of character we have, and thus - ;; how we need to pack it. + // Work out what type of character we have, and thus + // how we need to pack it. jsr get_packed_char_index cmp #$00 bne not_exception_char - ;; Char is an exception char. - ;; We need to either finish the previous byte with $xF, - ;; Or if there is no existing nybl, then we need to output - ;; either $FE or $FF, depending on whether this is the last - ;; byte or not + // Char is an exception char. + // We need to either finish the previous byte with $xF, + // Or if there is no existing nybl, then we need to output + // either $FE or $FF, depending on whether this is the last + // byte or not lda tokenise_work3 bne have_nybl_before_exception_char - ;; No nybl exists before the exception char, so prefix with $FE or $FF - ;; based on whether we are at the end of the input string or not + // No nybl exists before the exception char, so prefix with $FE or $FF + // based on whether we are at the end of the input string or not inx lda tokenise_work1 cmp #$01 beq at_end lda #$FF .byte $2C -at_end: LDA #$FE +at_end: + lda #$FE dex jsr write_unpacked_char - ;; Fall through + // Fall through output_exception_byte: lda $0200,x @@ -78,18 +79,18 @@ output_exception_byte: jmp consider_next_char have_nybl_before_exception_char: - ;; Or existing byte with #$0F, and clear nybl flag + // Or existing byte with #$0F, and clear nybl flag ldy tokenise_work2 lda $0100,y ora #$0f sta $0100,y inc tokenise_work2 - ;; FALL THROUGH + // FALL THROUGH write_literal_and_terminate_if_required: - ;; Clear have nybl flag + // Clear have nybl flag lda #$00 sta tokenise_work3 @@ -99,19 +100,19 @@ write_literal_and_terminate_if_required: jmp end_string_if_required end_string_if_required: - ;; Check if X points to last char of string to be packed + // Check if X points to last char of string to be packed inx lda tokenise_work1 cmp #$01 - beq + + beq !+ dex jmp consider_next_char -* +!: dex - ;; Fall through + // Fall through end_string: - ;; Write end of string sequence if required + // Write end of string sequence if required lda #$00 jsr write_unpacked_char rts @@ -124,53 +125,53 @@ write_unpacked_char: rts not_exception_char: - ;; It wasn't an exception char, so write the symbol out + // It wasn't an exception char, so write the symbol out cmp #$10 bcs whole_byte_symbol - ;; Nybl encoded value: Put in upper half or lower half of a byte? + // Nybl encoded value: Put in upper half or lower half of a byte? ldy tokenise_work3 bne store_low_nybl - ;; Store in high nybl -- so shift it into the hi nybl + // Store in high nybl -- so shift it into the hi nybl asl asl asl asl ldy tokenise_work2 sta $0100,y - bne stored_nybl ; Must be taken, as A cannot be $00 + bne stored_nybl // Must be taken, as A cannot be $00 store_low_nybl: - ;; Low nybl gets added to high nybl already stored in the byte + // Low nybl gets added to high nybl already stored in the byte ldy tokenise_work2 ora $0100,y sta $0100,y stored_nybl: - ;; Now toggle the nybl flag + // Now toggle the nybl flag lda tokenise_work3 eor #$ff sta tokenise_work3 - ;; And advance the offset if we filled this byte up - bne consider_next_char ; Taken if byte has a nybl free, i.e., don't advance pointer while half byte remains free + // And advance the offset if we filled this byte up + bne consider_next_char // Taken if byte has a nybl free, i.e., don't advance pointer while half byte remains free - ;; Count the filled up byte + // Count the filled up byte inc tokenise_work2 - ;; Add termination byte if required - ;; (This re-writes the same byte again, which we don't care about) + // Add termination byte if required + // (This re-writes the same byte again, which we don't care about) jmp end_string_if_required whole_byte_symbol: - ;; It's a $Fx symbol. - ;; But if we have a nybl to flush, then we handle it like - ;; a full exception character + // It's a $Fx symbol. + // But if we have a nybl to flush, then we handle it like + // a full exception character ldy tokenise_work3 beq nothing_to_flush - ;; Set low nybl to $F to mark next byte as literal + // Set low nybl to $F to mark next byte as literal ldy tokenise_work2 lda $0100,y ora #$0f @@ -180,30 +181,30 @@ whole_byte_symbol: jmp write_literal_and_terminate_if_required nothing_to_flush: - ;; Write the symbol as it is, or the literal - ;; if it has been passed to us via fall-through + // Write the symbol as it is, or the literal + // if it has been passed to us via fall-through jsr write_unpacked_char jmp end_string_if_required consider_next_char: - ;; Pack next char + // Pack next char inx dec tokenise_work1 - beq + + beq !+ jmp pack_char_loop -* - ;; Add 1 to length if nybl waiting to be flushed - ;; (but leave flag set so the caller knows if the - ;; bottom nybl might be different if the string were - ;; longer). +!: + // Add 1 to length if nybl waiting to be flushed + // (but leave flag set so the caller knows if the + // bottom nybl might be different if the string were + // longer). lda tokenise_work3 - beq + + beq !+ inc tokenise_work2 rts -* - ;; Last byte was full, so we need at $00 on the end - ;; (unless a $FE token was written 2 bytes ago) +!: + // Last byte was full, so we need at $00 on the end + // (unless a $FE token was written 2 bytes ago) ldy tokenise_work2 iny lda #$00 @@ -213,21 +214,21 @@ consider_next_char: rts get_packed_char_index: - ;; Find char in A in the packed char list, and return - ;; $1 - $E, $F1 - $FD if the charactar is abbreviable, - ;; or else return $00 if the character has to be stored literally. + // Find char in A in the packed char list, and return + // $1 - $E, $F1 - $FD if the charactar is abbreviable, + // or else return $00 if the character has to be stored literally. - ;; Y register and A are modified, as are processor flags. + // Y register and A are modified, as are processor flags. ldy #$00 find_char_loop: cmp packed_message_chars,y bne not_a_match enumerate: - ;; Is it a nybl abbreviable char? + // Is it a nybl abbreviable char? cpy #14 bcs not_nybl_char - ;; Yes, so add 1 and return it + // Yes, so add 1 and return it iny tya rts @@ -235,9 +236,9 @@ enumerate: not_nybl_char: cpy #27 bcs not_a_match - ;; It's a $Fx character. - ;; Since the lowest index is $E, and it should be encoded as $F1 - ;; we need to add $E3 + // It's a $Fx character. + // Since the lowest index is $E, and it should be encoded as $F1 + // we need to add $E3 tya clc adc #$E3 @@ -245,10 +246,10 @@ not_nybl_char: not_a_match: iny - ;; Loop until we find it, or we discover it isn't - ;; a character with a special encoding + // Loop until we find it, or we discover it isn't + // a character with a special encoding cpy #27 bne find_char_loop - ;; Not a char that we can pack, so return 0 + // Not a char that we can pack, so return 0 lda #$00 rts diff --git a/c64/basic/peek_pointer_null_check.s b/c64/basic/peek_pointer_null_check.s index ff30acfb..c594664c 100644 --- a/c64/basic/peek_pointer_null_check.s +++ b/c64/basic/peek_pointer_null_check.s @@ -1,5 +1,5 @@ - ;; Return C=1 if a pointer in BASIC memory space is NULL, else C=0 - ;; X = ZP pointer to check +// Return C=1 if a pointer in BASIC memory space is NULL, else C=0 +// X = ZP pointer to check peek_pointer_null_check: ldy #$00 @@ -11,10 +11,10 @@ peek_pointer_null_check: cmp #$00 bne ptr_not_null - ;; Pointer is NULL + // Pointer is NULL clc rts ptr_not_null: sec rts - + diff --git a/c64/basic/print_integer.s b/c64/basic/print_integer.s index f5d93fa7..ff9938fd 100644 --- a/c64/basic/print_integer.s +++ b/c64/basic/print_integer.s @@ -1,26 +1,27 @@ - ;; Works similar to $BDCD in original C64 BASIC - ;; XXX Should eventually get replaced by a more flexible and optimal routine. - ;; Temp result gets written to $0100-$0104 +// Works similar to $BDCD in original C64 BASIC +// XXX Should eventually get replaced by a more flexible and optimal routine. +// Temp result gets written to $0100-$0104 + print_integer: pha txa pha - ;; Clear temporary output + // Clear temporary output lda #$00 ldy #5 -* sta $0100,y +!: sta $0100,y dey - bpl - + bpl !- pla - ldy #23 ; 8 x 3 - 1 = offset of last digit of 128 + ldy #23 // 8 x 3 - 1 = offset of last digit of 128 lo_loop: cmp #$7f bcc bit_clear - ;; Bit set, so add the digits + // Bit set, so add the digits pha ldx #2 clc @@ -45,16 +46,16 @@ next_lo_bit: bcc lo_loop - ;; Now do the same for upper byte + // Now do the same for upper byte pla - ldy #39 ; 8 x 5 - 1 = offset of last digit of 32768 + ldy #39 // 8 x 5 - 1 = offset of last digit of 32768 hi_loop: cmp #$7f bcc bit_clear_hi - ;; Bit set, so add the digits + // Bit set, so add the digits pha ldx #4 clc @@ -67,8 +68,8 @@ hi_add_loop: dex bpl hi_add_loop pla - jmp next_hi_bit - + jmp next_hi_bit + bit_clear_hi: dey dey @@ -78,47 +79,47 @@ bit_clear_hi: next_hi_bit: asl cpy #$7f - bcc hi_loop + bcc hi_loop fix_carry: - - ;; Deal with any carries + + // Deal with any carries ldx #3 -carry_fix_loop: +carry_fix_loop: lda $0101,x cmp #10 - bcc + + bcc !+ inc $0100,x sec sbc #10 sta $0101,x jmp carry_fix_loop - -* dex + +!: dex bpl carry_fix_loop -post_carry: +post_carry: - ;; Got digits. - ;; Skip leading zeros, and print the resulting number + // Got digits. + // Skip leading zeros, and print the resulting number - ;; Skip leading zeros + // Skip leading zeros ldy #0 -* lda $0100,y +!: lda $0100,y bne found_start_of_number iny cpy #4 - bne - + bne !- -found_start_of_number: - ;; Print digits -* lda $0100,y +found_start_of_number: + // Print digits +!: lda $0100,y ora #$30 jsr JCHROUT iny cpy #5 - bne - + bne !- rts diff --git a/c64/basic/print_packed_message.s b/c64/basic/print_packed_message.s index 006bf70e..49b03f1c 100644 --- a/c64/basic/print_packed_message.s +++ b/c64/basic/print_packed_message.s @@ -1,41 +1,42 @@ - ;; This routine prints messages that have been packed - ;; using the make_error_tables program. - ;; The general idea is to save space in the ROM. +// This routine prints messages that have been packed +// using the make_error_tables program. +// The general idea is to save space in the ROM. + +// The output of make_error_tables is written to packed_messages.s, and +// contains the following: +// +// packed_message_words - List of nybl packed words. +// packed_message_tokens - List of tokens that get joined to make messages +// packed_message_chars - List of characters in messages sorted by frequency. + - ;; The output of make_error_tables is written to packed_messages.s, and - ;; contains the following: - ;; - ;; packed_message_words - List of nybl packed words. - ;; packed_message_tokens - List of tokens that get joined to make messages - ;; packed_message_chars - List of characters in messages sorted by frequency. - print_packed_message: - ;; X = message number + // .X = message number lda #$ff ldy #$ff -packed_message_search: +packed_message_search: iny cpx #$00 beq found_message_in_token_stream lda packed_message_tokens,y cmp #$ff - bne + + bne !+ dex -* +!: cpy #$ff bne packed_message_search - ;; Could not find message + // Could not find message sec rts found_message_in_token_stream: - ;; Now print each word in the message + // Now print each word in the message tya pha lda packed_message_tokens,y cmp #$ff - beq + + beq !+ jsr print_packed_word lda #$20 jsr JCHROUT @@ -43,50 +44,50 @@ found_message_in_token_stream: tay iny bne found_message_in_token_stream -* +!: pla - ;; Rub out space at the end + // Rub out space at the end lda #$14 jsr JCHROUT rts print_packed_word: - ;; A = the word to print + // A = the word to print tax - ;; Setup pointer to packed words + // Setup pointer to packed words lda #packed_message_words sta temp_string_ptr+1 - ;; Find the word in the list + // Find the word in the list ldy #$ff packed_word_search: iny cpx #$00 beq found_packed_word - ;; $x0 is an end of work marker + // $x0 is an end of work marker lda (temp_string_ptr),y and #$0f cmp #$00 - bne + + bne !+ dex -* - ;; $FE $xx is an end of work marker +!: + // $FE $xx is an end of work marker lda (temp_string_ptr),y cmp #$fe - bne + + bne !+ dex - iny ; skip next byte -* + iny // skip next byte +!: cmp #$ff - bne + - iny ; skip next byte -* + bne !+ + iny // skip next byte +!: - ;; Advance to next page if required + // Advance to next page if required cpy #$ff bne packed_word_search inc temp_string_ptr+1 @@ -94,8 +95,8 @@ packed_word_search: found_packed_word: - ;; Get pointer to start of packed word - ;; Make sure we don't wrap on a page boundary + // Get pointer to start of packed word + // Make sure we don't wrap on a page boundary tya clc adc temp_string_ptr+0 @@ -104,14 +105,14 @@ found_packed_word: adc #$00 sta temp_string_ptr+1 -print_packed_string: +print_packed_string: ldy #$ff next_packed_word_char: - ;; Y = offset into packed word data - 1 + // .Y = offset into packed word data - 1 iny - - ;; Check for end of word + + // Check for end of word lda (temp_string_ptr),y cmp #$00 beq end_of_packed_word @@ -122,31 +123,31 @@ next_packed_word_char: and #$f0 beq end_of_packed_word - ;; Check if it is an uncommon char + // Check if it is an uncommon char lda (temp_string_ptr),y and #$f0 cmp #$f0 beq is_uncommon_char - ;; Is not an uncommon char, so get char of upper nybl + // Is not an uncommon char, so get char of upper nybl lda (temp_string_ptr),y - ;; Put high nybl into low bits of X + // Put high nybl into low bits of X lsr lsr lsr lsr tax - ;; Save Y so it doesn't get clobbered by CHROUT + // Save Y so it doesn't get clobbered by CHROUT tya pha - ;; X=1-14 = first 14 chars, so subtract one + // X=1-14 = first 14 chars, so subtract one lda packed_message_chars-1,x jsr JCHROUT - ;; See if there is a char in the low nybl to print + // See if there is a char in the low nybl to print pla tay lda (temp_string_ptr),y @@ -155,54 +156,54 @@ next_packed_word_char: cmp #$0f beq no_lo_nybl_char -has_lo_nybl_char: - ;; We need to print the low nybl char as well +has_lo_nybl_char: + // We need to print the low nybl char as well tax tya pha - ;; Skip lower nybls of $F or $0 in nybl packed - ;; bytes, as these do not encode characters + // Skip lower nybls of $F or $0 in nybl packed + // bytes, as these do not encode characters cpx #$f - beq + -has_nybl: + beq !+ +has_nybl: cpx #0 - beq + + beq !+ - ;; X=1-14 = first 14 chars, so subtract one + // X=1-14 = first 14 chars, so subtract one lda packed_message_chars-1,x jsr JCHROUT -* +!: pla tay - ;; FALL THROUGH + // FALLTHROUGH no_lo_nybl_char: - ;; If current byte has $0F in low nybl, then the next - ;; byte is a whole byte. + // If current byte has $0F in low nybl, then the next + // byte is a whole byte. lda (temp_string_ptr),y and #$0f cmp #$0f beq next_is_literal_char -ready_for_next_char: +ready_for_next_char: cpy #$ff bne next_packed_word_char -end_of_packed_word: - ;; Hit end of packed data +end_of_packed_word: + // Hit end of packed data rts last_literal: jsr unpack_literal_char rts - + next_is_literal_char: jsr unpack_literal_char jmp ready_for_next_char -unpack_literal_char: - ;; Output the literal char, and ready for next char +unpack_literal_char: + // Output the literal char, and ready for next char iny tya pha @@ -211,16 +212,16 @@ unpack_literal_char: pla tay rts - + is_uncommon_char: - ;; Lower nybl has offset into low-frequency part of the table + // Lower nybl has offset into low-frequency part of the table lda (temp_string_ptr),y and #$0f clc adc #14 - ;; We need to print the low nybl char as well + // We need to print the low nybl char as well tax tya pha diff --git a/c64/basic/printf.s b/c64/basic/printf.s index 1769660a..3266710f 100644 --- a/c64/basic/printf.s +++ b/c64/basic/printf.s @@ -1,17 +1,17 @@ - ;; printf()-like routine for simplifying debugging +// printf()-like routine for simplifying debugging - ;; Prints the literal zero-terminated string that follows, - ;; which may also include special tokens that allow - ;; printing of hex byte and word values stored at the indicated - ;; addresses. +// Prints the literal zero-terminated string that follows, +// which may also include special tokens that allow +// printing of hex byte and word values stored at the indicated +// addresses. - ;; .byte 1,$byte = display byte as hex - ;; .byte 2,$low,$hi = display word as hex - ;; .byte $f0+n,$low,$hi = display byte at $hi$lo+n as hex +// .byte 1,$byte = display byte as hex +// .byte 2,$low,$hi = display word as hex +// .byte $f0+n,$low,$hi = display byte at $hi$lo+n as hex printf: - ;; Temporary storage is between end of screen at $0400 - ;; and the sprite pointers at $7f8 + // Temporary storage is between end of screen at $0400 + // and the sprite pointers at $7f8 sta $7f0 stx $7f1 sty $7f2 @@ -19,14 +19,14 @@ printf: pla sta $7f3 - ;; Set up read routine - lda #$ad ; LDA $nnnn + // Set up read routine + lda #$ad // LDA $nnnn sta $7f4 lda #$60 - sta $7f7 ; RTS + sta $7f7 // RTS - ;; Get PC of caller from the stack, so that - ;; we can parse through it + // Get PC of caller from the stack, so that + // we can parse through it pla clc adc #$01 @@ -39,8 +39,8 @@ printf_loop: jsr $7f4 cmp #$00 bne printf_continues - ;; Put return address on stack and restore - ;; registers + // Put return address on stack and restore + // registers lda $7f6 pha lda $7f5 @@ -56,33 +56,33 @@ printf_loop: printf_continues: cmp #$01 bne not_hexbyte - ;; Print a hex byte + // Print a hex byte - ;; Skip the token + // Skip the token jsr printf_advance - ;; Read the low byte + // Read the low byte jsr $7f4 - ;; Print as hex + // Print as hex jsr printf_printhexbyte jmp printf_nextchar not_hexbyte: cmp #$02 bne not_hexword - ;; Print a hex word + // Print a hex word - ;; Skip the token + // Skip the token jsr printf_advance jsr printf_advance - ;; Read the high byte + // Read the high byte jsr $7f4 - ;; Print as hex + // Print as hex jsr printf_printhexbyte - ;; Skip the token + // Skip the token jsr printf_retreat - ;; Read the low byte + // Read the low byte jsr $7f4 - ;; Print as hex + // Print as hex jsr printf_printhexbyte jsr printf_advance jmp printf_nextchar @@ -91,11 +91,11 @@ not_hexword: cmp #$f0 bcc not_pointer - ;; Treat two-byte arg as base address - ;; and lower 4 bits of token as offset from - ;; that location. + // Treat two-byte arg as base address + // and lower 4 bits of token as offset from + // that location. - ;; Get offset + // Get offset and #$0f tay @@ -111,7 +111,7 @@ not_hexword: jmp printf_nextchar not_pointer: - ;; Print character + // Print character jsr JCHROUT printf_nextchar: @@ -120,15 +120,15 @@ printf_nextchar: jmp printf_loop printf_advance: - ;; Advance pointer to next character + // Advance pointer to next character inc $7f5 - bne + + bne !+ inc $7f6 - * +!: rts printf_retreat: - ;; Retreat pointer to previous char + // Retreat pointer to previous char lda $7f5 sec sbc #1 @@ -139,7 +139,7 @@ printf_retreat: rts printf_printhexbyte: - ;; Print the hex value in .A as two digits, idea by Haubitze + // Print the hex value in .A as two digits, idea by Haubitze sed pha lsr diff --git a/c64/basic/ready_message.s b/c64/basic/ready_message.s index 87508bd6..3a349177 100644 --- a/c64/basic/ready_message.s +++ b/c64/basic/ready_message.s @@ -1,6 +1,6 @@ ready_message: - ;; See src/make_error_tables.c for packed message handling - ;; information. + // See src/make_error_tables.c for packed message handling + // information. ldx #29 jmp print_packed_message diff --git a/c64/basic/select_device.s b/c64/basic/select_device.s index f5939033..30f15150 100644 --- a/c64/basic/select_device.s +++ b/c64/basic/select_device.s @@ -1,19 +1,19 @@ select_device: - ;; Take last device number, make sure it's a drive - 8 or above. Above 30, - ;; although illegal for IEC we also consider a drive, as they exists - ;; drivers assigning these numbers to CBM-DOS capable devices - like some - ;; IEEE-488 carts. - ;; - ;; If current device is not a drive, set device to 8 (first drive number) - ;; Device number is left in X, for SETFLS Kernal routine + // Take last device number, make sure it's a drive - 8 or above. Above 30, + // although illegal for IEC we also consider a drive, as they exists + // drivers assigning these numbers to CBM-DOS capable devices - like some + // IEEE-488 carts. + // + // If current device is not a drive, set device to 8 (first drive number) + // Device number is left in X, for SETFLS Kernal routine - ;; Note: if tape support is introduced here, make sure DOS wedge won't get broken + // Note: if tape support is introduced here, make sure DOS wedge won't get broken ldx current_device_number cpx #$08 - bcs + + bcs !+ ldx #$08 -* +!: rts diff --git a/c64/basic/tokenise_line.s b/c64/basic/tokenise_line.s index 8de69947..38e412b0 100644 --- a/c64/basic/tokenise_line.s +++ b/c64/basic/tokenise_line.s @@ -1,18 +1,18 @@ - ;; Tokenise a line of BASIC - ;; Stored at $0200 - ;; Length in tokenise_work1 +// Tokenise a line of BASIC +// Stored at $0200 +// Length in tokenise_work1 tokenise_line: - ;; We need to consider each offset in the string to see if it matches - ;; a token. No BASIC keyword is > 7 bytes, so we need to start with that - ;; length (or remaining length of string) and count our way back down. - ;; This means we need separate start and end points to keep track of. + // We need to consider each offset in the string to see if it matches + // a token. No BASIC keyword is > 7 bytes, so we need to start with that + // length (or remaining length of string) and count our way back down. + // This means we need separate start and end points to keep track of. - ;; $0110 = offset into string - ;; $0111 = number of bytes to pack - ;; $0112 = offset into tokenised output - ;; $0113 = length of raw string + // $0110 = offset into string + // $0111 = number of bytes to pack + // $0112 = offset into tokenised output + // $0113 = length of raw string lda #$00 sta $0110 @@ -24,56 +24,56 @@ tokenise_line: tokenise_char: - ;; Check if we have reached end of the line? + // Check if we have reached end of the line? lda $0110 cmp $0113 - bne + + bne !+ - ;; End of line reached + // End of line reached - ;; Finished tokenising line - ;; Update tokenise_work1 and terminate with null + // Finished tokenising line + // Update tokenise_work1 and terminate with null ldx $0112 lda #$00 sta $0200,x stx tokenise_work1 - ;; Clear quote mode flag that is also used by KERNAL for screen display + // Clear quote mode flag that is also used by KERNAL for screen display lda #$00 sta quote_mode_flag rts -* - ;; More to do +!: + // More to do - ;; Maximum keyword length + // Maximum keyword length lda #7 sta $0111 tokenise_char_loop: - ;; Pack the word from the start (start = X, raw len = tokenise_work1) - ;; Returns packed length in tokenise_work2 and writes the packed - ;; word at $0100+ + // Pack the word from the start (start = X, raw len = tokenise_work1) + // Returns packed length in tokenise_work2 and writes the packed + // word at $0100+ ldx $0110 lda $0200,x cmp #$22 bne tk_not_quote - ;; Quote + // Quote lda quote_mode_flag eor #$ff sta quote_mode_flag jmp tk_literal_char tk_not_quote: - ;; Check for literal characters in various ranges - ;; (This just speeds the tokeniser up, by avoiding the packed token search - ;; for such characters). + // Check for literal characters in various ranges + // (This just speeds the tokeniser up, by avoiding the packed token search + // for such characters). - ;; SPACE and punctuation before +,- and * + // SPACE and punctuation before +,- and * cmp #$2a bcc tk_literal_char - ;; Don't try to tokenise digits + // Don't try to tokenise digits cmp #$30 bcc tk_might_be_keyword cmp #$3a @@ -81,41 +81,41 @@ tk_not_quote: jmp tk_literal_char tk_might_be_keyword: - ;; Don't tokenise in quote mode + // Don't tokenise in quote mode lda quote_mode_flag bne tk_literal_char - ;; Pack string + // Pack string ldx $0110 lda $0111 sta tokenise_work1 - ;; XXX - We should implement an optimisation where we - ;; trim the last symbol of successively, instead of re-packing the word - ;; again with one less char each time. - ;; XXX - We should limit the word length to the length of interesting chars - ;; that are available. + // XXX - We should implement an optimisation where we + // trim the last symbol of successively, instead of re-packing the word + // again with one less char each time. + // XXX - We should limit the word length to the length of interesting chars + // that are available. jsr pack_word lda tokenise_work2 cmp #$10 - bcc + - ;; Packed string too long + bcc !+ + // Packed string too long jmp do_STRING_TOO_LONG_error - * +!: - ;; Search for it in keywords + // Search for it in keywords jsr keyword_search - ;; Did we find a keyword? + // Did we find a keyword? bcc found_token_in_line - ;; Nope, so try shorter + // Nope, so try shorter dec $0111 bne tokenise_char_loop tk_literal_char: - ;; Is not a token, so copy to output verbatim + // Is not a token, so copy to output verbatim ldx $0110 ldy $0112 lda $0200,x @@ -123,68 +123,68 @@ tk_literal_char: inc $0112 inc $0110 - ;; Tokenise next char + // Tokenise next char jmp tokenise_char found_token_in_line: - ;; Got a token, so write it out + // Got a token, so write it out ldx $0112 sta $0200,x inx stx $0112 - ;; If it is REM, then lock us in quote mode to the end of the line + // If it is REM, then lock us in quote mode to the end of the line cmp #$8f bne not_rem sta quote_mode_flag not_rem: - ;; Now skip over the length of the token + // Now skip over the length of the token lda $0110 clc adc $0111 sta $0110 - ;; See if there is more of the line left to process + // See if there is more of the line left to process jmp tokenise_char - - - ;; Search for word in keyword list - ;; The packed form is canonical, so we can search for the keyword while - ;; it remains compressed. This also saves a little time. - ;; Algorithm is simply to find matching first bytes, and then look for - ;; the rest being a match. + + + // Search for word in keyword list + // The packed form is canonical, so we can search for the keyword while + // it remains compressed. This also saves a little time. + // Algorithm is simply to find matching first bytes, and then look for + // the rest being a match. keyword_search: - ;; Search for the compressed keyword stored at $0100 in the list - ;; of compressed keywords - - ;; tokenise_work1 = offset in line of input - ;; tokenise_work2 = length of token we are matching - ;; tokenise_work3 = offset in token list - ;; load_or_verify_or_tokenise_work5 = temporary work space - ;; X and Y registers used as temporary space. - ;; returns C=1 if no matching token, else C=0 and A=token + // Search for the compressed keyword stored at $0100 in the list + // of compressed keywords + // tokenise_work1 = offset in line of input + // tokenise_work2 = length of token we are matching + // tokenise_work3 = offset in token list + // load_or_verify_or_tokenise_work5 = temporary work space + // X and Y registers used as temporary space. + // returns C=1 if no matching token, else C=0 and A=token + lda #$00 sta tokenise_work1 sta tokenise_work3 next_kw_offset: - ;; Advance offset in compressed keyword list, to see if a match - ;; BEGINS here + // Advance offset in compressed keyword list, to see if a match + // BEGINS here - ;; Get count of bytes to compare + // Get count of bytes to compare lda tokenise_work2 sta load_or_verify_or_tokenise_work5 - - ;; Load current position + + // Load current position ldy tokenise_work3 ldx tokenise_work1 - - ;; Advance offset in compressed token list, and stop at the end + + // Advance offset in compressed token list, and stop at the end inc tokenise_work3 lda tokenise_work3 cmp #packed_keyword_table_len @@ -194,76 +194,76 @@ next_in_match: lda $0100,x cmp packed_keywords,y bne next_kw_offset - ;; Advance to next chars in source and target + // Advance to next chars in source and target inx iny - dec load_or_verify_or_tokenise_work5 ; Have we compared all bytes yet? + dec load_or_verify_or_tokenise_work5 // Have we compared all bytes yet? bne next_in_match - ;; Keyword matches! + // Keyword matches! - ;; Now make sure we started on a keyword boundary - ;; (we know we finished on one, because of the structure of the compressed - ;; keyword data). - ;; Offset 0 - ;; previous byte is $x0 - ;; two byte prior is $FE + // Now make sure we started on a keyword boundary + // (we know we finished on one, because of the structure of the compressed + // keyword data). + // Offset 0 + // previous byte is $x0 + // two byte prior is $FE - ;; Get offset of first byte of this token + // Get offset of first byte of this token ldx tokenise_work3 - dex ; pointer points one late, so rewind it + dex // pointer points one late, so rewind it - ;; At start of list? + // At start of list? cpx #$00 beq word_boundary dex - ;; Previous byte is $x0 end token? + // Previous byte is $x0 end token? lda packed_keywords,x and #$0f beq word_boundary dex - ;; Uber-previouss byte is $FE final literal token? + // Uber-previouss byte is $FE final literal token? lda packed_keywords,x cmp #$fe beq word_boundary - ;; Not a word boundary, so ignore + // Not a word boundary, so ignore jmp next_kw_offset word_boundary: - ;; Found a token whose offset is in tokenise_work3 - ;; Now trace back to the start of the compressed keyword list - ;; to work out what keyword number we are, so that we can return - ;; the token number. + // Found a token whose offset is in tokenise_work3 + // Now trace back to the start of the compressed keyword list + // to work out what keyword number we are, so that we can return + // the token number. ldy #$80 token_count_loop: lda packed_keywords,x cmp #$fe - bne + + bne !+ iny -* +!: and #$0f cmp #$00 - bne + + bne !+ iny -* +!: cpx #$00 - beq + + beq !+ dex jmp token_count_loop -* - +!: + tya clc rts - + done_searching_for_token: - ;; No token found + // No token found sec lda #$00 rts - + diff --git a/c64/basic/under_rom_routines.s b/c64/basic/under_rom_routines.s index eebaaa16..e0e5a385 100644 --- a/c64/basic/under_rom_routines.s +++ b/c64/basic/under_rom_routines.s @@ -1,19 +1,19 @@ - ;; IMPORTANT: - ;; These routines lengths cannot be changed without changing - ;; the aliases for peek_under_roms, poke_under_roms etc - ;; in ,aliases.s. - ;; Thus those addresses are expressed using formulae. +// IMPORTANT: +// These routines lengths cannot be changed without changing +// the aliases for peek_under_roms, poke_under_roms etc +// in ,aliases.s. +// Thus those addresses are expressed using formulae. install_ram_routines: - ;; Copy routines into place - ldx #ram_routines_len-1 -* + // Copy routines into place + ldx #ram_routines_end-ram_routines_start-1 +!: lda ram_routines_start,x sta tiny_nmi_handler,x dex - bpl - + bpl !- - ;; Point NMI handler to tiny_nmi_handler + // Point NMI handler to tiny_nmi_handler lda #tiny_nmi_handler @@ -23,14 +23,14 @@ install_ram_routines: ram_routines_start: - ;; XXX - Routine order must match that of the KERNAL version of the file. - ;; (since it has fewer routines) + // XXX - Routine order must match that of the KERNAL version of the file. + // (since it has fewer routines) tiny_nmi_handler_routine: inc missed_nmi_flag rti peek_under_roms_routine: php - ; Offset of arg of lda ($00),y + // Offset of arg of lda ($00),y stx peek_under_roms+pa-peek_under_roms_routine+1 jsr memmap_allram pa: lda ($00),y @@ -40,7 +40,7 @@ pa: lda ($00),y poke_under_roms_routine: php - ; Offset of arg of lda ($00),y + // Offset of arg of lda ($00),y stx poke_under_roms+pb-poke_under_roms_routine+1 jsr memmap_allram pb: sta ($00),y @@ -64,12 +64,12 @@ memmap_allram_routine: rts shift_mem_up_routine: - ;; Move memmove_size bytes from memmove_src to memmove_dst, - ;; where memmove_dst > memmove_src - ;; This means we have to copy from the back end down. - ;; This routine assumes the pointers are already pointed - ;; to the end of the areas, and that Y is correctly initialised - ;; to allow the copy to begin. + // Move memmove_size bytes from memmove_src to memmove_dst, + // where memmove_dst > memmove_src + // This means we have to copy from the back end down. + // This routine assumes the pointers are already pointed + // to the end of the areas, and that Y is correctly initialised + // to allow the copy to begin. php jsr memmap_allram smu1: @@ -85,12 +85,12 @@ smu1: jmp memmap_normal shift_mem_down_routine: - ;; Move memmove_size bytes from memmove_src to memmove_dst, - ;; where memmove_dst > memmove_src - ;; This means we have to copy from the back end down. - ;; This routine assumes the pointers are already pointed - ;; to the end of the areas, and that Y is correctly initialised - ;; to allow the copy to begin. + // Move memmove_size bytes from memmove_src to memmove_dst, + // where memmove_dst > memmove_src + // This means we have to copy from the back end down. + // This routine assumes the pointers are already pointed + // to the end of the areas, and that Y is correctly initialised + // to allow the copy to begin. php jsr memmap_allram smd1: @@ -105,7 +105,4 @@ smd1: plp jmp memmap_normal - ram_routines_end: - .alias ram_routines_len ram_routines_end-ram_routines_start - diff --git a/c64/basic/wedge_dos.s b/c64/basic/wedge_dos.s index ddef3a38..7259d131 100644 --- a/c64/basic/wedge_dos.s +++ b/c64/basic/wedge_dos.s @@ -1,161 +1,161 @@ -;; START wedge support +// START wedge support wedge_dos: - ;; Close all the channels, so that wedge has full control + // Close all the channels, so that wedge has full control jsr JCLALL - ;; Set file parameters, channel 15 is a typical one for commands - jsr select_device ; sets X register + // Set file parameters, channel 15 is a typical one for commands + jsr select_device // sets .X register lda #$0F ldy #$0F jsr JSETFLS - ;; Now we have to check what the user wants us to do + // Now we have to check what the user wants us to do - ;; Check if user asked for a status + // Check if user asked for a status ldy #$00 lda (basic_current_statement_ptr), y - bne + - jmp wedge_dos_status ; XXX try to optimize this, perhaps move 'wedge_dos_status' above? -* - ;; Check if asked for a directory + bne !+ + jmp wedge_dos_status // XXX try to optimize this, perhaps move 'wedge_dos_status' above? +!: + // Check if asked for a directory cmp #$24 - bne + + bne !+ jmp wedge_dos_directory -* - ;; Check if asked to change drive number, or if it is a regular command +!: + // Check if asked to change drive number, or if it is a regular command cmp #$30 - bcc wedge_dos_command ; char code before 0 + bcc wedge_dos_command // char code before 0 cmp #$3A - bcs wedge_dos_command ; char code after 9 + bcs wedge_dos_command // char code after 9 iny lda (basic_current_statement_ptr), y - beq wedge_dos_change_drive ; end of buffer + beq wedge_dos_change_drive // end of buffer cmp #$20 beq wedge_dos_change_drive - jmp - + jmp !- wedge_dos_command: - ;; Provide command name + // Provide command name jsr wedge_dos_setnam jsr JSETNAM jsr JOPEN - bcc + - jmp wedge_dos_basic_error ; XXX combine with other such jumps -* - ;; Retrieve status, print it if not OK + bcc !+ + jmp wedge_dos_basic_error // XXX combine with other such jumps +!: + // Retrieve status, print it if not OK jsr JCLALL jsr wedge_dos_status_get lda BUF+0 - cmp #$30 ; '0' + cmp #$30 // '0' bne wedge_dos_status_print lda BUF+1 - cmp #$30 ; '0' + cmp #$30 // '0' bne wedge_dos_status_print - ;; Clean-up and exit + // Clean-up and exit jmp wedge_dos_clean_exit wedge_dos_change_drive: - ;; Reuse the line number parser for device number retrieval + // Reuse the line number parser for device number retrieval jsr basic_parse_line_number lda basic_line_number+1 - beq + + beq !+ jmp do_ILLEGAL_QUANTITY_error -* +!: lda basic_line_number+0 cmp #$08 - bpl + - bcs + + bpl !+ + bcs !+ jmp do_ILLEGAL_DEVICE_NUMBER_error -* +!: sta current_device_number jmp basic_end_of_line wedge_dos_status_get: - ;; Here the flow is mostly the same as in the example from - ;; https://codebase64.org/doku.php?id=base:reading_the_error_channel_of_a_disk_drive + // Here the flow is mostly the same as in the example from + // https://codebase64.org/doku.php?id=base:reading_the_error_channel_of_a_disk_drive - ;; Set remaining file parameters, open the channel - lda #$00 ; empty file name + // Set remaining file parameters, open the channel + lda #$00 // empty file name jsr JSETNAM jsr JOPEN - bcc + - jmp wedge_dos_basic_error ; XXX combine with other such jumps -* + bcc !+ + jmp wedge_dos_basic_error // XXX combine with other such jumps +!: - ;; Set channel for input + // Set channel for input ldx #$0F jsr JCHKIN - bcc + - jmp wedge_dos_basic_error ; XXX combine with other such jumps -* - + bcc !+ + jmp wedge_dos_basic_error // XXX combine with other such jumps +!: + ldy #$00 -* - cpy #$50 ; buffer overflow protection - beq + - jsr JREADST ; retrieve errors - ;; XXX error in case of status != EOF - ;; Print out everything retrieved from the drive - bne + +!: + cpy #$50 // buffer overflow protection + beq !+ + jsr JREADST // retrieve errors + // XXX error in case of status != EOF + // Print out everything retrieved from the drive + bne !+ jsr JCHRIN bcc wedge_dos_x1 - jmp wedge_dos_basic_error ; XXX try to optimize this + jmp wedge_dos_basic_error // XXX try to optimize this wedge_dos_x1: sta BUF, y iny - jmp - -* + jmp !- +!: rts wedge_dos_status: jsr wedge_dos_status_get - ;; FALLTROUGH + // FALLTROUGH wedge_dos_status_print: - ;; Print buffered status + // Print buffered status ldx #$00 -* +!: dey - bmi + + bmi !+ lda BUF, x jsr JCHROUT inx - bne - -* - ;; Clean-up and exit + bne !- +!: + // Clean-up and exit jmp wedge_dos_clean_exit wedge_dos_directory: - ;; First change the secondary address to the one suitable for - ;; directory loading - lda #$00 ; logical device number + // First change the secondary address to the one suitable for + // directory loading + lda #$00 // logical device number ldx current_device_number ldy #$60 jsr JSETFLS - ;; Provide file name + // Provide file name jsr wedge_dos_setnam - ;; Open the file + // Open the file jsr JOPEN bcs wedge_dos_basic_error - ;; Set channel for file reading + // Set channel for file reading ldx #$00 jsr JCHKIN bcs wedge_dos_basic_error - ;; Ignore start address (2 first bytes) - XXX check for errors + // Ignore start address (2 first bytes) - XXX check for errors jsr JCHRIN bcs wedge_dos_basic_error jsr JCHRIN @@ -163,37 +163,37 @@ wedge_dos_directory: wedge_dos_directory_line: - ;; Load a single line, reuse BASIC input buffer + // Load a single line, reuse BASIC input buffer ldy #$FF -* +!: iny jsr JCHRIN bcs wedge_dos_basic_error sta BUF, y cpy #$50 - beq + ; line too long, terminate loading file + beq !+ // line too long, terminate loading file jsr JREADST - bne + ; end of file - cpy #$04 ; 2 bytes (pointer to next line) + 2 bytes (line number) - bcc - + bne !+ // end of file + cpy #$04 // 2 bytes (pointer to next line) + 2 bytes (line number) + bcc !- lda BUF, y - bne - - ;; End of line, but not end of file + bne !- + // End of line, but not end of file beq wedge_dos_directory_display -* +!: lda #K_STS_END_OF_FILE - sta IOSTATUS ; make sure end of file is marked - ;; FALLTROUGH + sta IOSTATUS // make sure end of file is marked + // FALLTROUGH wedge_dos_directory_display: - cpy #$05 ; protection against malformed directory + cpy #$05 // protection against malformed directory bcc wedge_dos_clean_exit - lda #$00 ; extra protection agains buffer overflow + lda #$00 // extra protection agains buffer overflow sta BUF, y - ;; Display line + // Display line ldx #BUF @@ -201,14 +201,14 @@ wedge_dos_directory_display: ldx #basic_current_line_ptr jsr list_single_line - ;; Read & display next line or quit + // Read & display next line or quit lda IOSTATUS beq wedge_dos_directory_line - ;; FALLTROUGH + // FALLTROUGH wedge_dos_clean_exit: jsr JCLALL - ;; Print new line + // Print new line lda #$0D jsr JCHROUT jmp basic_end_of_line @@ -222,17 +222,17 @@ wedge_dos_basic_error: jmp do_basic_error wedge_dos_setnam: - ;; Now determine the length of the 'file' name + // Now determine the length of the 'file' name ldy #$FF -* +!: iny lda (basic_current_statement_ptr), y - bne - + bne !- - ;; Set the name to open + // Set the name to open tya ldx basic_current_statement_ptr+0 ldy basic_current_statement_ptr+1 jmp JSETNAM -;; END wedge support +// END wedge support diff --git a/c64/kernal/,aliases.s b/c64/kernal/,aliases.s index b769b149..e2a275b5 100644 --- a/c64/kernal/,aliases.s +++ b/c64/kernal/,aliases.s @@ -1,73 +1,75 @@ -; Names of ZP and low memory locations -; (Only those of relevance for the KERNAL) -; (And only those for now that we feel the need to implement initially) -; (https://www.c64-wiki.com/wiki/Zeropage) +// Names of ZP and low memory locations +// (Only those of relevance for the KERNAL) +// (And only those for now that we feel the need to implement initially) +// (https://www.c64-wiki.com/wiki/Zeropage) - .alias kernal_load_or_verify_flag $93 - .alias current_file_num $98 - .alias input_device_number DFLTN - .alias cassette_buffer_bytes_used $A6 - .alias load_or_scroll_temp_pointer $AC - ;; We also use the following for temp colour pointer when scrolling - .alias load_save_verify_end_address $AE - .alias cassette_buffer_ptr $B2 - .alias current_logical_filenum $B8 - .alias current_secondary_address $B9 - .alias current_device_number $BA - .alias current_filename_ptr $BB - .alias load_save_end_ptr $C3 - .alias last_key_matrix_position $C5 - .alias keys_in_key_buffer $C6 - .alias reverse_video_flag $C7 - .alias end_of_input_line $C8 - .alias start_of_keyboard_input $C9 - .alias current_key_index_entry $CB - .alias cursor_blink_disable $CC - .alias cursor_blink_countdown $CD - .alias cursor_saved_character $CE - .alias cursor_is_visible $CF - .alias keyboard_input_ready $D0 - .alias current_screen_line_ptr $D1 - .alias current_screen_x $D3 - .alias quote_mode_flag $D4 - .alias logical_line_length $D5 - .alias current_screen_y $D6 - .alias last_printed_character_ascii $D7 - .alias insert_mode $D8 - ; Bits 0 -3 = bits 8-11 of screen line address - ; Bit 7 = line spans multiple physical lines - .alias screen_line_link_table $D9 - .alias current_screen_line_colour_ptr $F3 - .alias keyboard_decoding_table_ptr $F5 - .alias rs232_rx_buffer_ptr $F7 - .alias rs232_tx_buffer_ptr $F9 +// XXX get rid of this file, use ,aliases_ram_lowmem.s instead + + .label kernal_load_or_verify_flag = $93 + .label current_file_num = $98 + .label input_device_number = DFLTN + .label cassette_buffer_bytes_used = $A6 + .label load_or_scroll_temp_pointer = $AC + // We also use the following for temp colour pointer when scrolling + .label load_save_verify_end_address = $AE + .label cassette_buffer_ptr = $B2 + .label current_logical_filenum = $B8 + .label current_secondary_address = $B9 + .label current_device_number = $BA + .label current_filename_ptr = $BB + .label load_save_end_ptr = $C3 + .label last_key_matrix_position = $C5 + .label keys_in_key_buffer = $C6 + .label reverse_video_flag = $C7 + .label end_of_input_line = $C8 + .label start_of_keyboard_input = $C9 + .label current_key_index_entry = $CB + .label cursor_blink_disable = $CC + .label cursor_blink_countdown = $CD + .label cursor_saved_character = $CE + .label cursor_is_visible = $CF + .label keyboard_input_ready = $D0 + .label current_screen_line_ptr = $D1 + .label current_screen_x = $D3 + .label quote_mode_flag = $D4 + .label logical_line_length = $D5 + .label current_screen_y = $D6 + .label last_printed_character_ascii = $D7 + .label insert_mode = $D8 + // Bits 0 -3 = bits 8-11 of screen line address + // Bit 7 = line spans multiple physical lines + .label screen_line_link_table = $D9 + .label current_screen_line_colour_ptr = $F3 + .label keyboard_decoding_table_ptr = $F5 + .label rs232_rx_buffer_ptr = $F7 + .label rs232_tx_buffer_ptr = $F9 - ; "Compute's Mapping the 64" book - .alias keyboard_buffer $0277 - .alias text_colour $0286 ; p55 - .alias colour_under_cursor $0287 ; p56 - .alias key_buffer_size $0289 ; p57 + // "Compute's Mapping the 64" book + .label keyboard_buffer = $0277 + .label text_colour = $0286 // p55 + .label colour_under_cursor = $0287 // p56 + .label key_buffer_size = $0289 // p57 - ;; 0 = cursor keys, insert, delete and space repeat, but nothing else - ;; 128 = all keys repeat - ;; 64 = no keys repeat - .alias key_repeat_flags $028A ; p58 - ;; https://www.c64-wiki.com/wiki/Page_2 - .alias key_repeat_counter $028B - .alias key_first_repeat_delay $028C - ;; bit 0 = shift, 1 = Vendor Key, 2 = Control - .alias key_bucky_state $028D - .alias key_last_bucky_state $028E - .alias keyboard_decoding_ptr $028F - .alias enable_case_switch $0291 - .alias screen_scroll_disable $0292 + // 0 = cursor keys, insert, delete and space repeat, but nothing else + // 128 = all keys repeat + // 64 = no keys repeat + .label key_repeat_flags = $028A // p58 + // https://www.c64-wiki.com/wiki/Page_2 + .label key_repeat_counter = $028B + .label key_first_repeat_delay = $028C + // bit 0 = shift, 1 = Vendor Key, 2 = Control + .label key_bucky_state = $028D + .label key_last_bucky_state = $028E + .label keyboard_decoding_ptr = $028F + .label enable_case_switch = $0291 + .label screen_scroll_disable = $0292 - ;; Under-ROM routines - ;; (BASIC also includes them. XXX - We should de-duplicate them in a safe manner) - .alias missed_nmi_flag $2A7 - .alias tiny_nmi_handler $2A8 - .alias peek_under_roms tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine - .alias poke_under_roms tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine - .alias memmap_allram tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine - .alias memmap_normal tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine + // Under-ROM routines + // (BASIC also includes them. XXX - We should de-duplicate them in a safe manner) + .label missed_nmi_flag = $2A7 + .label tiny_nmi_handler = $2A8 + .label peek_under_roms = tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine + .label poke_under_roms = tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine + .label memmap_allram = tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine + .label memmap_normal = tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine diff --git a/c64/kernal/,target_generic/,hooks_generic.s b/c64/kernal/,target_generic/,hooks_generic.s index a2c8c1a6..84c261a2 100644 --- a/c64/kernal/,target_generic/,hooks_generic.s +++ b/c64/kernal/,target_generic/,hooks_generic.s @@ -1,6 +1,6 @@ -;; Target-specific hooks +// Target-specific hooks -.macro TARGET_HOOK_LOAD -.macend +.macro TARGET_HOOK_LOAD() { +} diff --git a/c64/kernal/,target_mega65/,hooks_mega65.s b/c64/kernal/,target_mega65/,hooks_mega65.s index a2c8c1a6..84c261a2 100644 --- a/c64/kernal/,target_mega65/,hooks_mega65.s +++ b/c64/kernal/,target_mega65/,hooks_mega65.s @@ -1,6 +1,6 @@ -;; Target-specific hooks +// Target-specific hooks -.macro TARGET_HOOK_LOAD -.macend +.macro TARGET_HOOK_LOAD() { +} diff --git a/c64/kernal/,target_ultimate64/,aliases_ultimate64.s b/c64/kernal/,target_ultimate64/,aliases_ultimate64.s index a4aabfaf..65e2d20a 100644 --- a/c64/kernal/,target_ultimate64/,aliases_ultimate64.s +++ b/c64/kernal/,target_ultimate64/,aliases_ultimate64.s @@ -1,57 +1,57 @@ -;; Registers according to Ultimate 64 Command Interface description, -;; https://1541u-documentation.readthedocs.io/en/latest/command%20interface.html -;; and ultimate_dos_v1.0.pdf and command_interface_v1.0.pdf by Gideon Zweijtzer +// Registers according to Ultimate 64 Command Interface description, +// https://1541u-documentation.readthedocs.io/en/latest/command%20interface.html +// and ultimate_dos_v1.0.pdf and command_interface_v1.0.pdf by Gideon Zweijtzer - ;; Command interface registers - .alias U64_CONTROL $DF1C ; write - .alias U64_STATUS $DF1C ; read - .alias U64_COMMAND_DATA $DF1D ; write - .alias U64_IDENTIFICATION $DF1D ; read - .alias U64_RESPONSE_DATA $DF1E ; read only - .alias U64_STATUS_DATA $DF1F ; read only + // Command interface registers + .label U64_CONTROL = $DF1C // write + .label U64_STATUS = $DF1C // read + .label U64_COMMAND_DATA = $DF1D // write + .label U64_IDENTIFICATION = $DF1D // read + .label U64_RESPONSE_DATA = $DF1E // read only + .label U64_STATUS_DATA = $DF1F // read only - ;; Constant for U64_IDENTIFICATION register - .alias U64_MAGIC_ID $C9 + // Constant for U64_IDENTIFICATION register + .const U64_MAGIC_ID = $C9 - ;; Constants for U64_CONTROL register - .alias U64_CTRL_BIT_PUSH_CMD $01 - .alias U64_CTRL_BIT_DATA_ACC $02 - .alias U64_CTRL_BIT_ABORT $04 - .alias U64_CTRL_BIT_CLR_ERR $08 + // Constants for U64_CONTROL register + .const U64_CTRL_BIT_PUSH_CMD = $01 + .const U64_CTRL_BIT_DATA_ACC = $02 + .const U64_CTRL_BIT_ABORT = $04 + .const U64_CTRL_BIT_CLR_ERR = $08 - ;; Constants for U64_STATUS register - .alias U64_STAT_BIT_CMD_BUSY $01 - .alias U64_STAT_BIT_DATA_ACC $02 - .alias U64_STAT_BIT_ABORT_P $04 - .alias U64_STAT_BIT_ERROR $08 - .alias U64_STAT_MASK_STATE $30 ; two bits! - .alias U64_STAT_BIT_STAT_AV $40 - .alias U64_STAT_BIT_DATA_AV $80 + // Constants for U64_STATUS register + .const U64_STAT_BIT_CMD_BUSY = $01 + .const U64_STAT_BIT_DATA_ACC = $02 + .const U64_STAT_BIT_ABORT_P = $04 + .const U64_STAT_BIT_ERROR = $08 + .const U64_STAT_MASK_STATE = $30 // two bits! + .const U64_STAT_BIT_STAT_AV = $40 + .const U64_STAT_BIT_DATA_AV = $80 - ;; Interface targets - .alias U64_TARGET_DOS1 $01 - .alias U64_TARGET_DOS2 $02 + // Interface targets + .const U64_TARGET_DOS1 = $01 + .const U64_TARGET_DOS2 = $02 - ;; DOS command codes - .alias U64_DOS_CMD_IDENTIFY $01 - .alias U64_DOS_CMD_OPEN_FILE $02 - .alias U64_DOS_CMD_CLOSE_FILE $03 - .alias U64_DOS_CMD_READ_DATA $04 - .alias U64_DOS_CMD_WRITE_DATA $05 - .alias U64_DOS_CMD_FILE_SEEK $06 - .alias U64_DOS_CMD_FILE_INFO $07 - .alias U64_DOS_CMD_CHANGE_DIR $11 - .alias U64_DOS_CMD_GET_PATH $12 - .alias U64_DOS_CMD_OPEN_DIR $13 - .alias U64_DOS_CMD_READ_DIR $14 - .alias U64_DOS_CMD_COPY_UI_PATH $15 - .alias U64_DOS_CMD_LOAD_REU $21 - .alias U64_DOS_CMD_SAVE_REU $22 - .alias U64_DOS_CMD_ECHO $F0 + // DOS command codes + .const U64_DOS_CMD_IDENTIFY = $01 + .const U64_DOS_CMD_OPEN_FILE = $02 + .const U64_DOS_CMD_CLOSE_FILE = $03 + .const U64_DOS_CMD_READ_DATA = $04 + .const U64_DOS_CMD_WRITE_DATA = $05 + .const U64_DOS_CMD_FILE_SEEK = $06 + .const U64_DOS_CMD_FILE_INFO = $07 + .const U64_DOS_CMD_CHANGE_DIR = $11 + .const U64_DOS_CMD_GET_PATH = $12 + .const U64_DOS_CMD_OPEN_DIR = $13 + .const U64_DOS_CMD_READ_DIR = $14 + .const U64_DOS_CMD_COPY_UI_PATH = $15 + .const U64_DOS_CMD_LOAD_REU = $21 + .const U64_DOS_CMD_SAVE_REU = $22 + .const U64_DOS_CMD_ECHO = $F0 - ;; DOS file opening constants - .alias U64_FA_READ $01 - .alias U64_FA_WRITE $02 - .alias U64_FA_CREATE_NEW $03 - .alias U64_FA_CREATE_ALWAYS $04 + // DOS file opening constants + .const U64_FA_READ = $01 + .const U64_FA_WRITE = $02 + .const U64_FA_CREATE_NEW = $03 + .const U64_FA_CREATE_ALWAYS = $04 diff --git a/c64/kernal/,target_ultimate64/,hooks_ultimate64.s b/c64/kernal/,target_ultimate64/,hooks_ultimate64.s index 03f6eeb8..efc1f52f 100644 --- a/c64/kernal/,target_ultimate64/,hooks_ultimate64.s +++ b/c64/kernal/,target_ultimate64/,hooks_ultimate64.s @@ -1,9 +1,9 @@ -;; Target-specific hooks +// Target-specific hooks -.macro TARGET_HOOK_LOAD - ;; XXX disabled for now - the current file opening API is not - ;; really suitable for easy usage from Kernal - ;; jsr u64_load -.macend +.macro TARGET_HOOK_LOAD() { + // XXX disabled for now - the current file opening API is not + // really suitable for easy usage from Kernal + // jsr u64_load +} diff --git a/c64/kernal/,target_ultimate64/u64_load.s.disabled b/c64/kernal/,target_ultimate64/u64_load.s.disabled index 07ddc298..7b585c1e 100644 --- a/c64/kernal/,target_ultimate64/u64_load.s.disabled +++ b/c64/kernal/,target_ultimate64/u64_load.s.disabled @@ -1,52 +1,53 @@ -;; -;; LOAD routine hook for fast loading via UltiDOS -;; +// +// LOAD routine hook for fast loading via UltiDOS +// u64_load: - ;; First check whether the command interface is enabled + // First check whether the command interface is enabled lda U64_IDENTIFICATION cmp #U64_MAGIC_ID - beq + + beq !+ u64_load_skip: rts -* - ;; XXX find out which device number softIEC is mapped to +!: + // XXX find out which device number softIEC is mapped to lda current_device_number - cmp #$20 ; for now use device number 32 + cmp #$20 // for now use device number 32 bne u64_load_skip - - ;; Takeover the flow completely + + // Takeover the flow completely pla pla - ;; Display SEARCHING FOR + filename + // Display SEARCHING FOR + filename jsr lvs_display_searching_for - ;; Whatever the interface was doing - ask to abort it + // Whatever the interface was doing - ask to abort it jsr u64_load_abort - - ;; Send a command to open the file + + // Send a command to open the file lda #U64_DOS_CMD_OPEN_FILE jsr u64_load_send_cmd lda #U64_FA_READ jsr u64_load_send_cmd jsr u64_load_send_filename jsr u64_load_finalize_cmd - - ;; Check status + + // Check status jsr u64_load_check_status bcs lvs_file_not_found_error - ;; Load first two bytes to determine start address + // Load first two bytes to determine start address + + // XXX - ;; XXX - jsr printf - .byte "DBG: NOT IMPLEMENTED",$0D,0 + .text "DBG: NOT IMPLEMENTED" + .byte $0D,0 jmp lvs_wrap_around_error rts @@ -54,77 +55,77 @@ u64_load_skip: u64_load_abort: lda #U64_CTRL_BIT_ABORT sta U64_CONTROL -* +!: lda U64_STATUS - bne - + bne !- rts u64_load_send_cmd: ldx #U64_TARGET_DOS2 - stx U64_COMMAND_DATA ; target - sta U64_COMMAND_DATA ; command code + stx U64_COMMAND_DATA // target + sta U64_COMMAND_DATA // command code rts u64_load_send_filename: ldy #0 u64_load_send_filename_loop: cpy FNLEN - bne+ + bne !+ rts -* +!: ldx # $A0-$BF + // $60-$7F -> $A0-$BF clc adc #$40 - ;; FALLTROUGH + // FALLTROUGH not_vendor: rts diff --git a/c64/kernal/chrout_real.s b/c64/kernal/chrout_real.s index d85084b0..190a4067 100644 --- a/c64/kernal/chrout_real.s +++ b/c64/kernal/chrout_real.s @@ -1,36 +1,36 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 278/279 -;; - [CM64] Compute's Mapping the Commodore 64 - page 228 -;; -;; CPU registers that has to be preserved (see [RG64]): .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 278/279 +// - [CM64] Compute's Mapping the Commodore 64 - page 228 +// +// CPU registers that has to be preserved (see [RG64]): .Y +// chrout_real: sta last_printed_character_ascii - ;; Save X and Y values - ;; (Confirmed by writing a test program that X and Y - ;; don't get modified, in agreement with C64 PRG's - ;; description of CHROUT) + // Save X and Y values + // (Confirmed by writing a test program that X and Y + // don't get modified, in agreement with C64 PRG's + // description of CHROUT) txa pha tya pha php - ;; Determine the device number + // Determine the device number lda DFLTO - cmp #$03 ; screen + cmp #$03 // screen beq chrout_screen jsr iec_check_devnum - bcs chrout_done_unknown_device ; not a supported device + bcs chrout_done_unknown_device // not a supported device chrout_iec: @@ -38,19 +38,19 @@ chrout_iec: jsr JCIOUT bcc chrout_done - ;; FALLTROUGH + // FALLTROUGH chrout_done_fail: jsr show_cursor_if_enabled plp - ;; Restore X and Y + // Restore X and Y pla tay pla tax - sec ; indicate failure + sec // indicate failure rts chrout_done_unknown_device: @@ -58,13 +58,13 @@ chrout_done_unknown_device: plp - ;; Restore X and Y + // Restore X and Y pla tay pla tax - ;; End wioth error + // End wioth error jmp lvs_device_not_found_error chrout_done: @@ -72,55 +72,55 @@ chrout_done: plp - ;; Restore X and Y + // Restore X and Y pla tay pla tax lda last_printed_character_ascii - clc ; indicate success + clc // indicate success rts chrout_screen: - ;; Crude implementation of character output - sei ;; XXX why do we need to disable interrupts? + // Crude implementation of character output + sei // XXX why do we need to disable interrupts? jsr hide_cursor_if_visible lda last_printed_character_ascii tax - ;; Check for special characters + // Check for special characters cmp #$00 bne not_00 jmp chrout_done not_00: - - ;; Linefeed (simply ignored) - ;; Trivia: BASIC does CRLF with READY. prompt + + // Linefeed (simply ignored) + // Trivia: BASIC does CRLF with READY. prompt cmp #$0a bne not_0a jmp chrout_done not_0a: - ;; Carriage return + // Carriage return cmp #$0d bne not_0d - ;; RETURN clears quote and insert modes + // RETURN clears quote and insert modes lda #$00 sta quote_mode_flag sta insert_mode jmp screen_advance_to_next_line -not_0d: +not_0d: cmp #$94 bne not_94 - ;; Insert (shift-DELETE) + // Insert (shift-DELETE) - ;; Abort if line already max length, ie 79th char is not a space + // Abort if line already max length, ie 79th char is not a space jsr get_current_line_logical_length cmp #79 bne definitely_not_too_long @@ -129,11 +129,11 @@ not_0d: cmp #$20 beq definitely_not_too_long - ;; Line is too long to extend + // Line is too long to extend jmp chrout_done -definitely_not_too_long: - ;; Work out if line needs to be expanded, and if so expand it +definitely_not_too_long: + // Work out if line needs to be expanded, and if so expand it ldy #39 lda (current_screen_line_ptr),y cmp #$20 @@ -142,18 +142,18 @@ definitely_not_too_long: jsr screen_grow_logical_line no_need_to_extend: - ;; Shuffle chars towards end of line + // Shuffle chars towards end of line jsr get_current_line_logical_length tay -* - ;; Note: While the following routine is obvious to any skilled - ;; in the art as the most obvious simple and efficient solution, - ;; if the screen writes are before the colour writes, it results - ;; in a relatively long verbatim stretch of bytes when compared to - ;; the C64 KERNAL. Thus we have swapped the order, just to reduce - ;; the potential for any argument of copyright infringement, even - ;; though we really don't believe that the routine can be copyrighted - ;; due to the lack of creativity. +!: + // Note: While the following routine is obvious to any skilled + // in the art as the most obvious simple and efficient solution, + // if the screen writes are before the colour writes, it results + // in a relatively long verbatim stretch of bytes when compared to + // the C64 KERNAL. Thus we have swapped the order, just to reduce + // the potential for any argument of copyright infringement, even + // though we really don't believe that the routine can be copyrighted + // due to the lack of creativity. dey lda (current_screen_line_colour_ptr),y iny @@ -165,36 +165,36 @@ no_need_to_extend: dey cpy current_screen_x - bne - + bne !- - ;; Increase insert mode count (which causes quote-mode like behaviour) + // Increase insert mode count (which causes quote-mode like behaviour) inc insert_mode - ;; Put space in the inserted gap + // Put space in the inserted gap lda #$20 sta (current_screen_line_ptr),y jmp chrout_done not_94: - ;; DELETE in insert mode embeds control character + // DELETE in insert mode embeds control character ldx insert_mode bne not_14 - + cmp #$14 bne not_14 - ;; Delete + // Delete ldx current_screen_x bne delete_non_zero_column delete_at_column_0: ldy current_screen_y bne not_row_0 - ;; delete from row 0, col 0 does nothing + // delete from row 0, col 0 does nothing jmp chrout_done not_row_0: - ;; Column 0 delete just moves us to the end of the - ;; previous line, without actually deleting anything + // Column 0 delete just moves us to the end of the + // previous line, without actually deleting anything dec current_screen_y jsr get_current_line_logical_length lda logical_line_length @@ -204,13 +204,13 @@ not_row_0: jmp chrout_done delete_non_zero_column: - ;; Copy rest of line down + // Copy rest of line down jsr get_current_line_logical_length ldy current_screen_x cpy logical_line_length beq done_delete dey -* +!: iny lda (current_screen_line_ptr),y dey @@ -221,20 +221,20 @@ delete_non_zero_column: sta (current_screen_line_colour_ptr),y iny cpy logical_line_length - bne - + bne !- - ;; Clear char at end of line + // Clear char at end of line jsr get_current_line_logical_length tay lda #$20 sta (current_screen_line_ptr),y - -done_delete: + +done_delete: dec current_screen_x jmp chrout_done -not_14: - - ;; Check for quote mode +not_14: + + // Check for quote mode ldx quote_mode_flag bne is_quote_mode ldx insert_mode @@ -242,79 +242,79 @@ not_14: jmp not_quote_mode is_quote_mode: - ;; Is it a control code? - ;; control codes are $00-$1f and $80-$9f - ;; (from reading C64 PRG p379-381) - ;; so we can just check if bits 5 or 6 are set, and if so, - ;; then it isn't a control character. + // Is it a control code? + // control codes are $00-$1f and $80-$9f + // (from reading C64 PRG p379-381) + // so we can just check if bits 5 or 6 are set, and if so, + // then it isn't a control character. pha and #$60 - bne + + bne !+ - ;; Yes, a control code in quote mode means we display it as a reverse character + // Yes, a control code in quote mode means we display it as a reverse character pla - ;; Low control codes are just +$80 + // Low control codes are just +$80 clc adc #$80 - ;; If it overflowed, then it is a high control code, - ;; so we need to make it be $80 + $40 + char - ;; as we will have flipped back to just $00 + char, we should - ;; now add $c0 if C is set from overflow + // If it overflowed, then it is a high control code, + // so we need to make it be $80 + $40 + char + // as we will have flipped back to just $00 + char, we should + // now add $c0 if C is set from overflow bcc low_ctrl_char - adc #$bf ; C=1, so adding $BF + C = add $C0 + adc #$bf // C=1, so adding $BF + C = add $C0 low_ctrl_char: jmp output_literal_char -* +!: pla -not_quote_mode: - - ;; Check for colours +not_quote_mode: + + // Check for colours ldx #$f colour_check_loop: cmp colour_codes,x - bne + + bne !+ stx text_colour jmp chrout_done - * dex +!: dex bpl colour_check_loop - ;; Compute's Mapping the 64 p38 + // Compute's Mapping the 64 p38 cmp #$12 bne not_12 lda #$80 sta reverse_video_flag jmp chrout_done not_12: - ;; Compute's Mapping the 64 p 38 + // Compute's Mapping the 64 p 38 cmp #$92 bne not_92 lda #$00 sta reverse_video_flag jmp chrout_done -not_92: - - ;; Check for cursor movement keys +not_92: + + // Check for cursor movement keys cmp #$11 bne not_11 lda current_screen_x clc adc #40 sta current_screen_x - ;; We need to advance the pointer manually, as normalising - ;; now will break things. The pointer update is required - ;; so that we can tell if we really are on the bottom phys - ;; screen line or not + // We need to advance the pointer manually, as normalising + // now will break things. The pointer update is required + // so that we can tell if we really are on the bottom phys + // screen line or not jsr scroll_up_if_on_last_line jsr calculate_screen_line_pointer jmp chrout_done -not_11: +not_11: cmp #$1d bne not_1d inc current_screen_x jsr calculate_screen_line_pointer jmp chrout_done -not_1d: +not_1d: cmp #$91 bne not_91 lda current_screen_x @@ -323,15 +323,15 @@ not_1d: sta current_screen_x jsr calculate_screen_line_pointer jmp chrout_done -not_91: +not_91: cmp #$9d bne not_9d dec current_screen_x jsr calculate_screen_line_pointer jmp chrout_done -not_9d: - - ;; Home cursor +not_9d: + + // Home cursor cmp #$13 bne not_13 lda #0 @@ -341,49 +341,49 @@ not_9d: jmp chrout_done not_13: - ;; Clear screen + // Clear screen cmp #$93 bne not_clearscreen jsr clear_screen jmp chrout_done -not_clearscreen: - - ;; Convert PETSCII to screen code +not_clearscreen: - ;; Don't print other control codes + // Convert PETSCII to screen code + + // Don't print other control codes cmp #$1f - bcs + + bcs !+ jmp chrout_done -* +!: - ;; Codes $C0-$DF become $40-$5F - ;; But + // Codes $C0-$DF become $40-$5F + // But cmp #$e0 - bcs + + bcs !+ cmp #$c0 - bcc + + bcc !+ and #$7f jmp not_high_char -* - ;; Range $20-$3F is unchanged +!: + // Range $20-$3F is unchanged cmp #$40 bcc not_high_char - - ;; Unshifted letters and symbols from $40-$5F - ;; all end up being -$40 - ;; (C64 PRG p376) - ;; But anything >= $80 needs to be -$40 - ;; (C64 PRG p380-381) - ;; And bit 7 should be cleared, only to be - ;; set by reverse video + // Unshifted letters and symbols from $40-$5F + // all end up being -$40 + // (C64 PRG p376) + + // But anything >= $80 needs to be -$40 + // (C64 PRG p380-381) + // And bit 7 should be cleared, only to be + // set by reverse video sec sbc #$40 - ;; Fix shifted chars by adding $20 again + // Fix shifted chars by adding $20 again cmp #$20 bcc not_high_char cmp #$40 @@ -391,51 +391,51 @@ not_clearscreen: clc adc #$20 -not_high_char: +not_high_char: chrout_l1: + +output_literal_char: -output_literal_char: - - ;; Write normal character on the screen + // Write normal character on the screen pha ldy current_screen_x - ora reverse_video_flag ; Compute's Mapping the 64 p38 + ora reverse_video_flag // Compute's Mapping the 64 p38 sta (current_screen_line_ptr),y - ;; Decrement number of chars waiting to be inserted + // Decrement number of chars waiting to be inserted lda insert_mode - beq + + beq !+ dec insert_mode -* +!: pla cmp #$22 bne not_quote - ;; Toggle quote flag if required + // Toggle quote flag if required lda quote_mode_flag eor #$80 sta quote_mode_flag -not_quote: - - ;; Set colour +not_quote: + + // Set colour lda text_colour sta (current_screen_line_colour_ptr),y - ;; Advance the column, and scroll screen down if we need - ;; to insert a 2nd line in this logical line. - ;; (eg Compute's Mapping the 64 p41) + // Advance the column, and scroll screen down if we need + // to insert a 2nd line in this logical line. + // (eg Compute's Mapping the 64 p41) ldx current_screen_y iny sty current_screen_x cpy #40 - bne + + bne !+ jsr screen_grow_logical_line ldy current_screen_x -* +!: cpy #80 bcc no_screen_advance_to_next_line lda #0 @@ -446,35 +446,35 @@ no_screen_advance_to_next_line: screen_grow_logical_line: ldy current_screen_y - ;; Don't grow line if it is already grown + // Don't grow line if it is already grown lda screen_line_link_table,y - bpl + + bpl !+ jmp done_grow_line -* +!: lda #$80 sta screen_line_link_table,y - ;; Now make space for the extra line added. - ;; If we are on the last physical line of the screen, - ;; Then we need to scroll the screen up + // Now make space for the extra line added. + // If we are on the last physical line of the screen, + // Then we need to scroll the screen up jsr scroll_up_if_on_last_line - ;; Scroll screen down to make space - ;; As we are scrolling down, we start from the end, - ;; and work backwards. We can't be as simple and efficient - ;; here as we are for scrolling up, because we don't know - ;; how much must be scrolled. - ;; Simple solution is to work out how many physical lines - ;; need shifting down, and then move lines at a time after - ;; initialising the pointers to the end area of the screen. + // Scroll screen down to make space + // As we are scrolling down, we start from the end, + // and work backwards. We can't be as simple and efficient + // here as we are for scrolling up, because we don't know + // how much must be scrolled. + // Simple solution is to work out how many physical lines + // need shifting down, and then move lines at a time after + // initialising the pointers to the end area of the screen. ldx #25-2 ldy #0 count_rows_loop: dex lda screen_line_link_table,y - bpl + + bpl !+ dex -* iny +!: iny cpy current_screen_y bne count_rows_loop @@ -482,14 +482,14 @@ count_rows_loop: beq no_copy_down bmi no_copy_down - ;; Set pointers to end of screen line, and one line - ;; above. (It is always one physical line, because - ;; this can only happen when expanding a line from 40 to - ;; 80 characters). - ;; XXX - This is not very efficient, and longer than it - ;; needs to be. Better would be to work out size to - ;; copy, and count it down in a pointer somewhere, so - ;; that loop iteration logic is simpler. + // Set pointers to end of screen line, and one line + // above. (It is always one physical line, because + // this can only happen when expanding a line from 40 to + // 80 characters). + // XXX - This is not very efficient, and longer than it + // needs to be. Better would be to work out size to + // copy, and count it down in a pointer somewhere, so + // that loop iteration logic is simpler. lda HIBASE clc adc #3 @@ -502,7 +502,7 @@ count_rows_loop: lda #<$03C0 sta current_screen_line_ptr+0 sta current_screen_line_colour_ptr+0 - ;; souce address is line above + // souce address is line above sec sbc #40 sta load_or_scroll_temp_pointer+0 @@ -518,11 +518,11 @@ cl_inner: dey bpl cl_inner - ;; Decrement all pointers by 40 - ;; Low bytes are in common pairs + // Decrement all pointers by 40 + // Low bytes are in common pairs - ;; Old source is new destination - ;; Use different registers to minimise byte similarity with C64 KERNAl + // Old source is new destination + // Use different registers to minimise byte similarity with C64 KERNAl ldy load_or_scroll_temp_pointer+1 sty current_screen_line_ptr+1 lda load_save_verify_end_address+1 @@ -531,7 +531,7 @@ cl_inner: sty current_screen_line_ptr+0 sty current_screen_line_colour_ptr+0 - ;; Decrementing source pointers + // Decrementing source pointers lda load_or_scroll_temp_pointer+0 sec sbc #<40 @@ -540,7 +540,7 @@ cl_inner: lda load_or_scroll_temp_pointer+1 sbc #>40 sta load_or_scroll_temp_pointer+1 - ;; convert to screen equivalent + // convert to screen equivalent sec sbc HIBASE clc @@ -550,31 +550,31 @@ cl_inner: dex bne copy_line_down_loop -no_copy_down: +no_copy_down: jsr calculate_screen_line_pointer - ;; Erase newly inserted line + // Erase newly inserted line ldy #79 - * +!: lda text_colour sta (current_screen_line_colour_ptr),y lda #$20 sta (current_screen_line_ptr),y dey cpy #40 - bne - + bne !- rts done_grow_line: -not_last_line: +not_last_line: rts scroll_up_if_on_last_line: - ;; Colour RAM is always in fixed place, so is easiest - ;; to use to check if we are on the last line. - ;; The last line is at $D800 + 24*40 = $DBC0 + // Colour RAM is always in fixed place, so is easiest + // to use to check if we are on the last line. + // The last line is at $D800 + 24*40 = $DBC0 lda current_screen_line_colour_ptr+1 cmp #>$DBC0 bne not_last_line @@ -593,13 +593,13 @@ is_last_line: dec current_screen_y - ;; FALL THROUGH + // FALL THROUGH scroll_screen_up: - ;; Now scroll the whole screen up either one or two lines - ;; based on whether the first screen line is linked or not. + // Now scroll the whole screen up either one or two lines + // based on whether the first screen line is linked or not. - ;; Get pointers to start of screen + colour RAM + // Get pointers to start of screen + colour RAM lda HIBASE sta current_screen_line_ptr+1 sta load_or_scroll_temp_pointer+1 @@ -610,17 +610,17 @@ scroll_screen_up: sta current_screen_line_ptr+0 sta current_screen_line_colour_ptr+0 - ;; Get pointers to screen/colour RAM source + // Get pointers to screen/colour RAM source lda screen_line_link_table+0 - bmi + + bmi !+ lda #40 - .byte $2C ; BIT $nnnn to skip next instruction - * + .byte $2C // BIT $nnnn to skip next instruction +!: lda #80 sta load_or_scroll_temp_pointer+0 sta load_save_verify_end_address+0 - ;; Copy first three pages + // Copy first three pages ldy #$00 ldx #3 scroll_copy_loop: @@ -639,9 +639,9 @@ scroll_copy_loop: dex bne scroll_copy_loop - ;; Copy last partial page - ;; We need to copy 1000-(3*256)-line length - ;; = 232 - line length + // Copy last partial page + // We need to copy 1000-(3*256)-line length + // = 232 - line length lda load_or_scroll_temp_pointer+0 lda #232 sec @@ -656,7 +656,7 @@ scroll_copy_loop2: dex bne scroll_copy_loop2 - ;; Fill in scrolled up area + // Fill in scrolled up area ldx load_or_scroll_temp_pointer+0 scroll_copy_loop3: lda text_colour @@ -667,7 +667,7 @@ scroll_copy_loop3: dex bne scroll_copy_loop3 - ;; Shift line linkage list + // Shift line linkage list ldy #0 ldx #24 link_copy: @@ -676,20 +676,20 @@ link_copy: iny dex bne link_copy - ;; Clear line link flag of last line + // Clear line link flag of last line stx screen_line_link_table+24 - ;; Restore correct line pointers + // Restore correct line pointers jsr calculate_screen_line_pointer rts -get_current_line_logical_length: +get_current_line_logical_length: ldy current_screen_y lda screen_line_link_table,y bpl line_not_linked_del lda #79 - .byte $2c ; BIT absolute mode, which we use to skip the next two instruction bytes + .byte $2c // BIT absolute mode, which we use to skip the next two instruction bytes line_not_linked_del: lda #39 sta logical_line_length @@ -697,21 +697,21 @@ line_not_linked_del: screen_advance_to_next_line: - ;; jsr hide_cursor_if_visible + // jsr hide_cursor_if_visible - ;; Go to start of line + // Go to start of line lda #0 sta current_screen_x - ;; Advance line number + // Advance line number ldy current_screen_y - ;; Do quick fix to line pointer to work out if it is off - ;; the bottom of the screen. + // Do quick fix to line pointer to work out if it is off + // the bottom of the screen. ldx #40 lda screen_line_link_table,y - bmi + + bmi !+ .byte $2c -* ldx #80 +!: ldx #80 txa clc adc current_screen_line_ptr+0 @@ -722,22 +722,22 @@ screen_advance_to_next_line: inc current_screen_y - ;; Check if it will trigger scrolling - ;; Work out if we have gone off the bottom of the screen? - ;; 1040 > 1024, so if high byte of screen pointer is >= (HIBASE+4), - ;; then we are off the bottom of the screen + // Check if it will trigger scrolling + // Work out if we have gone off the bottom of the screen? + // 1040 > 1024, so if high byte of screen pointer is >= (HIBASE+4), + // then we are off the bottom of the screen lda current_screen_line_ptr+1 sec sbc HIBASE cmp #3 - bcc + + bcc !+ lda current_screen_line_ptr+0 cmp #$e7 - bcc + + bcc !+ - ;; Off the bottom of the screen + // Off the bottom of the screen jsr scroll_screen_up -* +!: jsr calculate_screen_line_pointer @@ -751,68 +751,68 @@ add_40_to_screen_x: rts normalise_screen_x_y: - ;; Normalise X and Y values + // Normalise X and Y values - ;; If X < 0, then make X = X + 40 (or 80, if previous line is linked) -* lda current_screen_x + // If X < 0, then make X = X + 40 (or 80, if previous line is linked) +!: lda current_screen_x bpl x_not_negative dec current_screen_y - ;; Check that we didn't go backwards off the top of the screen - bpl + + // Check that we didn't go backwards off the top of the screen + bpl !+ lda #0 sta current_screen_y -* jsr add_40_to_screen_x +!: jsr add_40_to_screen_x - ;; Check if line is linked, if so, add 40 again + // Check if line is linked, if so, add 40 again ldy current_screen_y lda screen_line_link_table,y - bpl + + bpl !+ jsr add_40_to_screen_x -* +!: x_not_negative: - ;; Work out if X is too big + // Work out if X is too big ldy current_screen_y lda screen_line_link_table,y - bpl + + bpl !+ lda #79 - .byte $2C ; BIT $nnnn, used to skip next instruction -* lda #39 + .byte $2C // BIT $nnnn, used to skip next instruction +!: lda #39 cmp current_screen_x bcs x_not_too_big - ;; X value is too big, so subtract 40 and increment Y + // X value is too big, so subtract 40 and increment Y lda current_screen_x sec sbc #40 sta current_screen_x inc current_screen_y -x_not_too_big: +x_not_too_big: - ;; Make sure Y isn't negative + // Make sure Y isn't negative lda current_screen_y - bpl + + bpl !+ lda #0 sta current_screen_y -* - ;; Make sure Y isn't too large for absolute size of - ;; screen +!: + // Make sure Y isn't too large for absolute size of + // screen cmp #24 - bcc + + bcc !+ lda #24 sta current_screen_y -* - ;; Make sure Y isn't too much for the screen, taking - ;; into account the line link table - ldy #24 ; max allowable line +!: + // Make sure Y isn't too much for the screen, taking + // into account the line link table + ldy #24 // max allowable line ldx #0 -link_count_loop: +link_count_loop: lda screen_line_link_table,x - bpl + + bpl !+ dey -* inx +!: inx cpx #25 bne link_count_loop tya @@ -826,29 +826,29 @@ y_ok: calculate_screen_line_pointer: jsr normalise_screen_x_y - ;; Reset pointer to start of screen + // Reset pointer to start of screen lda HIBASE sta current_screen_line_ptr+1 lda #0 sta current_screen_line_ptr+0 - ;; Add 40 for every line, or 80 if the lines are linked + // Add 40 for every line, or 80 if the lines are linked ldx current_screen_y -* - ;; Stop if we have counted enough lines - beq + +!: + // Stop if we have counted enough lines + beq !+ - ;; Add 40 or 80 based on whether the line is linked - ;; or not. + // Add 40 or 80 based on whether the line is linked + // or not. ldy #40 - ;; -1 offset is because we count down from N to 1, not - ;; N-1 to 0. + // -1 offset is because we count down from N to 1, not + // N-1 to 0. lda screen_line_link_table-1,x bpl cslp_l1 ldy #80 cslp_l1: - ;; Add computed line length to pointer value + // Add computed line length to pointer value tya clc adc current_screen_line_ptr+0 @@ -857,15 +857,15 @@ cslp_l1: adc #0 sta current_screen_line_ptr+1 - ;; Loop back to next line + // Loop back to next line dex - jmp - -* + jmp !- +!: - ;; FALL THROUGH + // FALL THROUGH update_colour_line_pointer: - ;; Now setup pointer to colour RAM + // Now setup pointer to colour RAM lda current_screen_line_ptr+0 sta current_screen_line_colour_ptr+0 lda current_screen_line_ptr+1 @@ -896,6 +896,6 @@ advance_screen_pointer_40_bytes: jmp update_colour_line_pointer colour_codes: - ;; CHR$ codes for the 16 colours + // CHR$ codes for the 16 colours .byte 144,5,28,159,156,30,31,158 .byte 129,149,150,151,152,153,154,155 diff --git a/c64/kernal/cint_real.s b/c64/kernal/cint_real.s index 50e1d689..401db85c 100644 --- a/c64/kernal/cint_real.s +++ b/c64/kernal/cint_real.s @@ -1,24 +1,24 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 280 -;; - [CM64] Compute's Mapping the Commodore 64 - page 242 -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 280 +// - [CM64] Compute's Mapping the Commodore 64 - page 242 +// +// CPU registers that has to be preserved (see [RG64]): none +// cint_real: - ;; According to [CM64], this routine checks for PAL/NTSC. It's definitely not done - ;; within the 'BRK' part, this can be easily checked - POKE something - ;; to address 678 on a real C64, press STOP+RESTORE, the value won't change + // According to [CM64], this routine checks for PAL/NTSC. It's definitely not done + // within the 'BRK' part, this can be easily checked - POKE something + // to address 678 on a real C64, press STOP+RESTORE, the value won't change - ;; Detect video system (PAL/NTSC), use Graham's method, as it's short and reliable - ;; see here: https://codebase64.org/doku.php?id=base:detect_pal_ntsc + // Detect video system (PAL/NTSC), use Graham's method, as it's short and reliable + // see here: https://codebase64.org/doku.php?id=base:detect_pal_ntsc - lda #$C8 ; preparation, as the VIC might be uninitialized + lda #$C8 // preparation, as the VIC might be uninitialized sta VIC_SCROLX cint_w0: @@ -28,18 +28,18 @@ cint_w1: beq cint_w1 bmi cint_w0 - ;; Result in A, if no interrupt happened during the test: - ;; #$37 -> 312 rasterlines, PAL, VIC 6569 - ;; #$06 -> 263 rasterlines, NTSC, VIC 6567R8 - ;; #$05 -> 262 rasterlines, NTSC, VIC 6567R56A + // Result in A, if no interrupt happened during the test: + // #$37 -> 312 rasterlines, PAL, VIC 6569 + // #$06 -> 263 rasterlines, NTSC, VIC 6567R8 + // #$05 -> 262 rasterlines, NTSC, VIC 6567R56A cmp #$07 bcs cint_pal cint_ntsc: - ;; NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), - ;; is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles + // NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), + // is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles ldy #<17045 ldx #>17045 @@ -48,51 +48,51 @@ cint_ntsc: stx CIA1_TIMAHI lda #$00 - beq + + beq !+ cint_pal: lda #$01 -* +!: sta PALNTSC -cint_brk: ; entry for BRK and STOP+RESTORE - XXX, where should it start? +cint_brk: // entry for BRK and STOP+RESTORE - XXX, where should it start? jsr setup_vicii - ;; Initialise cursor blink flags (Compute's Mapping the 64 p215) + // Initialise cursor blink flags (Compute's Mapping the 64 p215) lda #$00 sta cursor_blink_disable - ;; Set keyboard decode vector (Compute's Mapping the 64 p215) + // Set keyboard decode vector (Compute's Mapping the 64 p215) - ;; Set initial variables for our improved keyboard scan routine - lda #$ff + // Set initial variables for our improved keyboard scan routine + lda #$FF ldx #6 -* sta BufferOld,x +!: sta BufferOld,x dex - bpl - + bpl !- sta BufferQuantity - ;; Set key repeat delay (Compute's Mapping the 64 p215) - ;; Making some numbers up here: Repeat every ~1/10th sec - ;; But require key to be held for ~1/3sec before - ;; repeating (Compute's Mapping the 64 p58) - ldx #22-2 ; Fudge factor to match speed + // Set key repeat delay (Compute's Mapping the 64 p215) + // Making some numbers up here: Repeat every ~1/10th sec + // But require key to be held for ~1/3sec before + // repeating (Compute's Mapping the 64 p58) + ldx #22-2 // Fudge factor to match speed stx key_first_repeat_delay - ;; Set current colour for text (Compute's Mapping the 64 p215) - ldx #$01 ; default is light blue ($0E), but we use a different one + // Set current colour for text (Compute's Mapping the 64 p215) + ldx #$01 // default is light blue ($0E), but we use a different one stx text_colour - ;; Set maximum keyboard buffer size (Compute's Mapping the 64 p215) + // Set maximum keyboard buffer size (Compute's Mapping the 64 p215) ldx #10 stx key_buffer_size - ;; Put non-zero value in enable_case_switch + // Put non-zero value in enable_case_switch stx enable_case_switch - ;; Set default I/O devices (see SCINIT description at http://sta.c64.org/cbm64krnfunc.html) + // Set default I/O devices (see SCINIT description at http://sta.c64.org/cbm64krnfunc.html) jsr clrchn_reset - ;; Fallthrough/jump to screen clear routine (Compute's Mapping the 64 p215) + // Fallthrough/jump to screen clear routine (Compute's Mapping the 64 p215) jmp clear_screen diff --git a/c64/kernal/ciout.s b/c64/kernal/ciout.s index 26095a85..3d84170c 100644 --- a/c64/kernal/ciout.s +++ b/c64/kernal/ciout.s @@ -1,37 +1,37 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 279/280 -;; - [CM64] Compute's Mapping the Commodore 64 - page 224 -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 279/280 +// - [CM64] Compute's Mapping the Commodore 64 - page 224 +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -ciout: +CIOUT: pha lda C3PO bne ciout_send_byte - ;; Nothing to send - set buffer as valid, store byte there + // Nothing to send - set buffer as valid, store byte there inc C3PO - ;; Clear carry flag to indicate success + // Clear carry flag to indicate success clc ciout_store_in_buffer: - ;; Store in the buffer data to be sent next, return + // Store in the buffer data to be sent next, return pla sta BSOUR rts ciout_send_byte: - clc ; don't send with EOI + clc // don't send with EOI jsr iec_tx_byte - inc C3PO ; iec_tx_byte sets it to 0, but we still have something to send + inc C3PO // iec_tx_byte sets it to 0, but we still have something to send jmp ciout_store_in_buffer diff --git a/c64/kernal/clall_real.s b/c64/kernal/clall_real.s index 33649858..2a24af72 100644 --- a/c64/kernal/clall_real.s +++ b/c64/kernal/clall_real.s @@ -1,38 +1,38 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 281 -;; - [CM64] Compute's Mapping the Commodore 64 - page 230 -;; -;; CPU registers that has to be preserved (see [RG64]): .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 281 +// - [CM64] Compute's Mapping the Commodore 64 - page 230 +// +// CPU registers that has to be preserved (see [RG64]): .Y +// clall_real: - ;; Store .Y register + // Store .Y register tya pha - ;; Original routine probably just sets LDTND to 0, but this is not really safe, - ;; so we actually close all the channels; at least IDE64 does the same for - ;; it's channels, see CLALL description in the IDE64 User's Guide -* + // Original routine probably just sets LDTND to 0, but this is not really safe, + // so we actually close all the channels; at least IDE64 does the same for + // it's channels, see CLALL description in the IDE64 User's Guide +!: ldy LDTND - beq + + beq !+ dey lda LAT, y jsr JCLOSE - jmp - -* - ;; Restore .Y register + jmp !- +!: + // Restore .Y register pla tay - ;; 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too - jsr clrchn + // 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too + jsr CLRCHN - ;; Not sure whether original Kernal does so, but it seems sane to also clear possible errors + // Not sure whether original Kernal does so, but it seems sane to also clear possible errors jmp kernalstatus_reset diff --git a/c64/kernal/close_load.s b/c64/kernal/close_load.s index f594590f..b899cf21 100644 --- a/c64/kernal/close_load.s +++ b/c64/kernal/close_load.s @@ -1,23 +1,23 @@ -;; Common ppart of CLOSE and LOAD routines +// Common ppart of CLOSE and LOAD routines close_load: tax - ;; Command drive to stop talking and to close the file - jsr untlk + // Command drive to stop talking and to close the file + jsr UNTLK txa - jsr listen + jsr LISTEN - lda #$E0 ; CLOSE command + lda #$E0 // CLOSE command sta IEC_TMP2 jsr iec_tx_command jsr iec_tx_command_finalize - ;; Tell drive to unlisten - jsr unlsn + // Tell drive to unlisten + jsr UNLSN rts diff --git a/c64/kernal/clrchn_real.s b/c64/kernal/clrchn_real.s index 2abee15e..b12177af 100644 --- a/c64/kernal/clrchn_real.s +++ b/c64/kernal/clrchn_real.s @@ -1,35 +1,35 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 282 -;; - [CM64] Compute's Mapping the Commodore 64 - page 230 -;; -;; CPU registers that has to be preserved (see [RG64]): .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 282 +// - [CM64] Compute's Mapping the Commodore 64 - page 230 +// +// CPU registers that has to be preserved (see [RG64]): .Y +// clrchn_real: - ;; Handle IEC input device + // Handle IEC input device lda DFLTN jsr iec_check_devnum - bcs + - ;; Previous device was IEC one - send UNTALK first - jsr untlk -* - ;; Restore output device to default + bcs !+ + // Previous device was IEC one - send UNTALK first + jsr UNTLK +!: + // Restore output device to default lda DFLTO jsr iec_check_devnum - bcs + - ;; Handle IEC output device - jsr unlsn -* -clrchn_reset: ;; entry needed by CHRIN - ;; Set input device number to keyboard + bcs !+ + // Handle IEC output device + jsr UNLSN +!: +clrchn_reset: // entry needed by CHRIN + // Set input device number to keyboard lda #$00 sta DFLTN - ;; Set output device number to screen + // Set output device number to screen lda #$03 sta DFLTO diff --git a/c64/kernal/e544.clear_screen.s b/c64/kernal/e544.clear_screen.s index 431c571e..d0e0e639 100644 --- a/c64/kernal/e544.clear_screen.s +++ b/c64/kernal/e544.clear_screen.s @@ -1,10 +1,10 @@ - ;; Clear screen and initialise line link table - ;; (Compute's Mapping the 64 p215-216) +// Clear screen and initialise line link table +// (Compute's Mapping the 64 p215-216) clear_screen: - ;; Clear line link table - ;; (Compute's Mapping the 64 p215) + // Clear line link table + // (Compute's Mapping the 64 p215) lda #$00 ldy #24 @@ -13,27 +13,27 @@ clearscreen_l1: dey bpl clearscreen_l1 - ;; Y now = #$FF + // Y now = #$FF - ;; Clear screen RAM. - ;; We should do this at HIBASE, which annoyingly - ;; is no ZP, so we need to make a vector - ;; (Compute's Mapping the 64 p216) - ;; Get pointer to the screen into current_screen_line_ptr - ;; as it is the first appropriate place for it found when - ;; searching through the ZP allocations listed in - ;; Compute's Mapping the 64 + // Clear screen RAM. + // We should do this at HIBASE, which annoyingly + // is no ZP, so we need to make a vector + // (Compute's Mapping the 64 p216) + // Get pointer to the screen into current_screen_line_ptr + // as it is the first appropriate place for it found when + // searching through the ZP allocations listed in + // Compute's Mapping the 64 sta current_screen_line_ptr+0 - lda hibase + lda HIBASE sta current_screen_line_ptr+1 - ldx #$03 ; countdown for pages to update - iny ; Y now = #$00 - lda #$20 ; space character + ldx #$03 // countdown for pages to update + iny // Y now = #$00 + lda #$20 // space character clearscreen_l2: sta (current_screen_line_ptr),y iny bne clearscreen_l2 - ;; To draw only 1000 bytes, add 250 to address each time + // To draw only 1000 bytes, add 250 to address each time lda current_screen_line_ptr clc adc #<250 @@ -41,20 +41,20 @@ clearscreen_l2: lda current_screen_line_ptr+1 adc #>250 sta current_screen_line_ptr+1 - lda #$20 ; get space character again + lda #$20 // get space character again dex bpl clearscreen_l2 - ;; Clear colour RAM - ;; (Compute's Mapping the 64 p216) + // Clear colour RAM + // (Compute's Mapping the 64 p216) lda text_colour clearscreen_l3: sta $d800,y sta $d900,y sta $da00,y - sta $db00-24,y ; so we only erase 1000 bytes + sta $db00-24,y // so we only erase 1000 bytes iny bne clearscreen_l3 - ;; (Compute's Mapping the 64 p216) + // (Compute's Mapping the 64 p216) jmp home_cursor diff --git a/c64/kernal/e5a0.setup_vicii.s b/c64/kernal/e5a0.setup_vicii.s index d2483a45..4fb95bc8 100644 --- a/c64/kernal/e5a0.setup_vicii.s +++ b/c64/kernal/e5a0.setup_vicii.s @@ -1,20 +1,20 @@ setup_vicii: - ;; Set up default IO values (Compute's Mapping the 64 p215) - lda #$1B ; Enable text mode + // Set up default IO values (Compute's Mapping the 64 p215) + lda #$1B // Enable text mode sta VIC_SCROLY - lda #$C8 ; 40 column etc + lda #$C8 // 40 column etc sta VIC_SCROLX - ;; Compute's Mapping the 64, p156 - ;; We use a different colour scheme of white text on all blue + // Compute's Mapping the 64, p156 + // We use a different colour scheme of white text on all blue lda #$06 sta VIC_EXTCOL sta VIC_BGCOL0 - ;; Turn off sprites (observed hanging around after running programs and resetting) + // Turn off sprites (observed hanging around after running programs and resetting) lda #$00 sta VIC_SPENA - ;;FALLTROUGH + // FALLTROUGH diff --git a/c64/kernal/errors.s b/c64/kernal/errors.s index 1f18f5e1..70f9847e 100644 --- a/c64/kernal/errors.s +++ b/c64/kernal/errors.s @@ -1,7 +1,7 @@ -;; Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306 +// Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306 -kernalerror_ROUTINE_TERMINATED: ; by a STOP key +kernalerror_ROUTINE_TERMINATED: // by a STOP key lda #K_ERR_ROUTINE_TERMINATED sec rts @@ -56,20 +56,20 @@ kernalerror_TOP_MEM_RS232: sec rts -;; Kernal status codes are described in 'Commodore 64 Programmer's Reference Guide', page 292 +// Kernal status codes are described in 'Commodore 64 Programmer's Reference Guide', page 292 kernalstatus_reset: lda #$00 sta IOSTATUS rts -kernalstatus_TIMEOUT_WRITE: ;; XXX detect this! +kernalstatus_TIMEOUT_WRITE: // XXX detect this! lda IOSTATUS ora #K_STS_TIMEOUT_WRITE sta IOSTATUS rts -kernalstatus_TIMEOUT_READ: ;; XXX detect this! +kernalstatus_TIMEOUT_READ: // XXX detect this! lda IOSTATUS ora #K_STS_TIMEOUT_READ sta IOSTATUS diff --git a/c64/kernal/f13e.getin.s b/c64/kernal/f13e.getin.s index e8961cb4..485535b0 100644 --- a/c64/kernal/f13e.getin.s +++ b/c64/kernal/f13e.getin.s @@ -1,27 +1,27 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 283 -;; - [CM64] Compute's Mapping the Commodore 64 - page 227/228 -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 283 +// - [CM64] Compute's Mapping the Commodore 64 - page 227/228 +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -;; XXX currently does not preserve registers, to be fixed! +// XXX currently does not preserve registers, to be fixed! -getin: +GETIN: - ;; Wait for a key + // Wait for a key lda keys_in_key_buffer - bne + + bne !+ - ;; Nothing in keyboard buffer to read + // Nothing in keyboard buffer to read sec lda #$00 rts -* +!: lda keyboard_buffer pha diff --git a/c64/kernal/f157.chrin.jmp.s b/c64/kernal/f157.chrin.jmp.s index c063c752..b1b7c234 100644 --- a/c64/kernal/f157.chrin.jmp.s +++ b/c64/kernal/f157.chrin.jmp.s @@ -1,6 +1,6 @@ -;; Our implementation is longer than the original one, -;; placing it here would cause a collision with CHROUT +// Our implementation is longer than the original one, +// placing it here would cause a collision with CHROUT -chrin: +CHRIN: jmp chrin_real diff --git a/c64/kernal/f1ca.chrout.jmp.s b/c64/kernal/f1ca.chrout.jmp.s index 02e434ea..6a1993c3 100644 --- a/c64/kernal/f1ca.chrout.jmp.s +++ b/c64/kernal/f1ca.chrout.jmp.s @@ -1,6 +1,6 @@ -;; Our implementation is longer than the original one, -;; placing it here would cause a collision with CHKIN +// Our implementation is longer than the original one, +// placing it here would cause a collision with CHKIN -chrout: +CHROUT: jmp chrout_real diff --git a/c64/kernal/f20e.chkin.jmp.s b/c64/kernal/f20e.chkin.jmp.s index bed06f58..ba38979d 100644 --- a/c64/kernal/f20e.chkin.jmp.s +++ b/c64/kernal/f20e.chkin.jmp.s @@ -1,6 +1,6 @@ -;; In our implementation CHKIN and CKOUT are closely tied, -;; placing it here would cause a collision +// In our implementation CHKIN and CKOUT are closely tied, +// placing it here would cause a collision -chkin: +CHKIN: jmp chkin_real diff --git a/c64/kernal/f250.ckout.jmp.s b/c64/kernal/f250.ckout.jmp.s index 671d44bd..18cfbffc 100644 --- a/c64/kernal/f250.ckout.jmp.s +++ b/c64/kernal/f250.ckout.jmp.s @@ -1,6 +1,6 @@ -;; In our implementation CHKIN and CKOUT are closely tied, -;; placing it here would cause a collision +// In our implementation CHKIN and CKOUT are closely tied, +// placing it here would cause a collision -ckout: +CKOUT: jmp ckout_real diff --git a/c64/kernal/f291.close.s b/c64/kernal/f291.close.s index 693362ce..5b45bf47 100644 --- a/c64/kernal/f291.close.s +++ b/c64/kernal/f291.close.s @@ -1,49 +1,49 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 281/282 -;; - [CM64] Compute's Mapping the Commodore 64 - page 229/230 -;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc (IEC command) -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 281/282 +// - [CM64] Compute's Mapping the Commodore 64 - page 229/230 +// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc (IEC command) +// +// CPU registers that has to be preserved (see [RG64]): none +// -close: +CLOSE: - ;; XXX this needs more testing (opening 10 files at once, closing in various orders, etc) once the code is more mature + // XXX this needs more testing (opening 10 files at once, closing in various orders, etc) once the code is more mature - ;; Find the LAT / SAT / FAT entry which LAT corresponds to A + // Find the LAT / SAT / FAT entry which LAT corresponds to A jsr find_fls - bcs close_error_not_found ;; XXX can we report error in IOSTATUS here? + bcs close_error_not_found // XXX can we report error in IOSTATUS here? - ;; We have the entry index in Y - check whether this is IEC device + // We have the entry index in Y - check whether this is IEC device lda FAT, y jsr iec_check_devnum bcs close_remove_from_table - ;; IEC device + // IEC device - jsr iec_tx_flush ; make sure no byte is awaiting - lda SAT, y ; get secondary address + jsr iec_tx_flush // make sure no byte is awaiting + lda SAT, y // get secondary address cmp #$60 - bne + - ;; workaround for using CLOSE on reading executable - XXX is this a proper way? + bne !+ + // workaround for using CLOSE on reading executable - XXX is this a proper way? jsr close_load jmp close_remove_from_table -* - ora $E0 ; CLOSE command +!: + ora $E0 // CLOSE command sta IEC_TMP2 jsr iec_tx_command bcs close_remove_from_table jsr iec_tx_command_finalize close_remove_from_table: - ;; Remove channel from the table + // Remove channel from the table iny cpy #$0A - bpl + + bpl !+ lda LAT, y sta LAT-1, y lda FAT, y @@ -51,14 +51,14 @@ close_remove_from_table: lda SAT, y sta SAT-1, y jmp close_remove_from_table -* - ;; Decrement the list size variable +!: + // Decrement the list size variable dec LDTND - clc ; report success - not sure if original CLOSE does this, but it's nevertheless a good practice + clc // report success - not sure if original CLOSE does this, but it's nevertheless a good practice rts close_error_not_found: - sec ; report success - not sure if original CLOSE does this, but it's nevertheless a good practice + sec // report success - not sure if original CLOSE does this, but it's nevertheless a good practice rts diff --git a/c64/kernal/f32f.clall.jmp.s b/c64/kernal/f32f.clall.jmp.s index 56567151..f0538e90 100644 --- a/c64/kernal/f32f.clall.jmp.s +++ b/c64/kernal/f32f.clall.jmp.s @@ -1,6 +1,6 @@ -;; Our implementation is longer than the original one, -;; placing it here would cause a collision with CLRCHN +// Our implementation is longer than the original one, +// placing it here would cause a collision with CLRCHN -clall: +CLALL: jmp clall_real diff --git a/c64/kernal/f333.clrchn.jmp.s b/c64/kernal/f333.clrchn.jmp.s index ac23dc8e..7c56fe28 100644 --- a/c64/kernal/f333.clrchn.jmp.s +++ b/c64/kernal/f333.clrchn.jmp.s @@ -1,6 +1,6 @@ -;; Our implementation is longer than the original one, -;; placing it here would cause a collision with OPEN +// Our implementation is longer than the original one, +// placing it here would cause a collision with OPEN -clrchn: +CLRCHN: jmp clrchn_real diff --git a/c64/kernal/f34a.open.s b/c64/kernal/f34a.open.s index 81192de3..a669d960 100644 --- a/c64/kernal/f34a.open.s +++ b/c64/kernal/f34a.open.s @@ -1,23 +1,23 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 289 -;; - [CM64] Compute's Mapping the Commodore 64 - page 230/231 -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 289 +// - [CM64] Compute's Mapping the Commodore 64 - page 230/231 +// +// CPU registers that has to be preserved (see [RG64]): none +// -open: +OPEN: - ;; Reset status + // Reset status jsr kernalstatus_reset - ;; Check if the logical file number is unique + // Check if the logical file number is unique ldy LDTND -* - beq + +!: + beq !+ dey lda LAT, y cmp current_logical_filenum @@ -25,23 +25,23 @@ open: jmp kernalerror_FILE_ALREADY_OPEN open_not_yet_open: cpy #$00 - jmp - -* - ;; Check if we have space in tables + jmp !- +!: + // Check if we have space in tables ldy LDTND cpy #$0A bcc open_has_space -* - ;; Table is full +!: + // Table is full jmp kernalerror_TOO_MANY_OPEN_FILES open_has_space: - ;; Update the tables + // Update the tables - ;; LAT / FAT / SAT support implemented according to - ;; 'Compute's Mapping the Commodore 64', page 52 + // LAT / FAT / SAT support implemented according to + // 'Compute's Mapping the Commodore 64', page 52 lda current_logical_filenum sta LAT, y @@ -53,16 +53,16 @@ open_has_space: iny sty LDTND - ;; Check for command to send + // Check for command to send lda FNLEN beq open_done_success - ;; Check for IEC device + // Check for IEC device lda current_device_number jsr iec_check_devnum bcc open_iec - ;; FALLTROUGH + // FALLTROUGH open_done_success: clc @@ -70,21 +70,21 @@ open_done_success: open_iec: - ;; We have a command to send to IEC device - jsr listen - bcc + + // We have a command to send to IEC device + jsr LISTEN + bcc !+ jmp kernalerror_DEVICE_NOT_FOUND -* +!: lda current_secondary_address jsr iec_cmd_open - bcc + + bcc !+ jmp kernalerror_DEVICE_NOT_FOUND -* +!: - ;; We need our helpers to get to filenames under ROMs or IO area + // We need our helpers to get to filenames under ROMs or IO area jsr install_ram_routines - ;; Send command ('file name') + // Send command ('file name') jsr lvs_send_file_name jmp open_done_success diff --git a/c64/kernal/f4a5.load.s b/c64/kernal/f4a5.load.s index 0bc03517..cbf0b1d7 100644 --- a/c64/kernal/f4a5.load.s +++ b/c64/kernal/f4a5.load.s @@ -1,146 +1,146 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 286 -;; - [CM64] Compute's Mapping the Commodore 64 - page 231 -;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 286 +// - [CM64] Compute's Mapping the Commodore 64 - page 231 +// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// +// CPU registers that has to be preserved (see [RG64]): none +// - ;; Expects that SETLFS and SETNAM are called before hand. - ;; $YYXX = load address. - ;; (ignored if SETLFS channel = 1, i.e., like ,8,1) - ;; If A=1 then VERIFY instead of LOAD. - ;; On exit, $YYXX is the highest address into which data - ;; will have been placed. + // Expects that SETLFS and SETNAM are called before hand. + // $YYXX = load address. + // (ignored if SETLFS channel = 1, i.e., like ,8,1) + // If A=1 then VERIFY instead of LOAD. + // On exit, $YYXX is the highest address into which data + // will have been placed. - ;; XXX honor MSGFLG bit 6 - ;; XXX add VERIFY support + // XXX honor MSGFLG bit 6 + // XXX add VERIFY support -load: +LOAD: - ;; Are we loading or verifying? + // Are we loading or verifying? sta VERCK - ;; Store start address of LOAD + // Store start address of LOAD stx STAL+0 sty STAL+1 - ;; Reset status + // Reset status jsr kernalstatus_reset - ;; We need our helpers to get to filenames under ROMs or IO area + // We need our helpers to get to filenames under ROMs or IO area jsr install_ram_routines - ;; Allow platform-specific routine to takeover the flow - `TARGET_HOOK_LOAD + // Allow platform-specific routine to takeover the flow + TARGET_HOOK_LOAD() - ;; Check whether we support the requested device + // Check whether we support the requested device lda current_device_number and #$FC - bne + - jmp lvs_illegal_device_number ; device number below 4, not an IEC device -* - ;; Device numbers above 30 are also illegal (see https://www.pagetable.com/?p=1031), - ;; as the protocol combines device number with command code int one byte, - ;; above 30 it is no longer possible (UNLISTEN and UNTALK codes prevent using - ;; number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only - ;; for devices 0-3; in our implementation LISTEN / TALK will cause device - ;; not present detected for numbers above 30 + bne !+ + jmp lvs_illegal_device_number // device number below 4, not an IEC device +!: + // Device numbers above 30 are also illegal (see https://www.pagetable.com/?p=1031), + // as the protocol combines device number with command code int one byte, + // above 30 it is no longer possible (UNLISTEN and UNTALK codes prevent using + // number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only + // for devices 0-3; in our implementation LISTEN / TALK will cause device + // not present detected for numbers above 30 - ;; Display SEARCHING FOR + filename + // Display SEARCHING FOR + filename jsr lvs_display_searching_for - ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf - ;; p13, 16; also p16 tells us this routine doesn't mess with the file table - ;; in the C64, only in the drive. + // http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // p13, 16; also p16 tells us this routine doesn't mess with the file table + // in the C64, only in the drive. - ;; Call device to LISTEN (p16) + // Call device to LISTEN (p16) lda current_device_number - jsr listen - bcc + - jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine -* - ;; Open channel 0 (reserved for file reading) + jsr LISTEN + bcc !+ + jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine +!: + // Open channel 0 (reserved for file reading) lda #$00 jsr iec_cmd_open - bcc + - jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine -* - ;; Send file name + bcc !+ + jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine +!: + // Send file name jsr lvs_send_file_name - bcc + - jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine -* - ;; Now command device to talk (p16) + bcc !+ + jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine +!: + // Now command device to talk (p16) lda current_device_number - jsr talk - bcc + - jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine -* - lda #$60 ; open channel / data (p3) , required according to p13 + jsr TALK + bcc !+ + jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine +!: + lda #$60 // open channel / data (p3) , required according to p13 sta IEC_TMP2 jsr iec_tx_command - bcc + - jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine -* - ;; We are currently talker, so do the IEC turn around so that we - ;; are the listener (p16) + bcc !+ + jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine +!: + // We are currently talker, so do the IEC turn around so that we + // are the listener (p16) jsr iec_turnaround_to_listen - bcc + - jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine -* - ;; Get load address and store it if secondary address is zero + bcc !+ + jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine +!: + // Get load address and store it if secondary address is zero jsr iec_rx_byte - bcc + - jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine -* + bcc !+ + jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine +!: ldx current_secondary_address - beq + + beq !+ sta STAL+0 -* +!: jsr iec_rx_byte - bcc + - jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine -* + bcc !+ + jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine +!: ldx current_secondary_address - beq + + beq !+ sta STAL+1 -* - ;; Display start address +!: + // Display start address jsr lvs_display_loading_verifying load_loop: - ;; We are now ready to receive bytes + // We are now ready to receive bytes jsr iec_rx_byte - bcc + - jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine -* - ;; Handle the byte (store in memory / verify) + bcc !+ + jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine +!: + // Handle the byte (store in memory / verify) jsr lvs_handle_byte_load_verify - bcc + - jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine -* - ;; Advance pointer to data + bcc !+ + jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine +!: + // Advance pointer to data jsr lvs_advance_pointer - bcc + + bcc !+ jmp lvs_wrap_around_error -* - ;; Check for EOI - if so, this was the last byte +!: + // Check for EOI - if so, this was the last byte lda IOSTATUS and #K_STS_EOI beq load_loop - ;; Display end address + // Display end address jsr lvs_display_done - ;; Close file on drive + // Close file on drive lda current_device_number jsr close_load - ;; Return last address + // Return last address jmp lvs_return_last_address diff --git a/c64/kernal/f5ed.save.s b/c64/kernal/f5ed.save.s index e98d030f..44c6eb15 100644 --- a/c64/kernal/f5ed.save.s +++ b/c64/kernal/f5ed.save.s @@ -1,13 +1,13 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 293/294 -;; - [CM64] Compute's Mapping the Commodore 64 - page 231/232 -;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 293/294 +// - [CM64] Compute's Mapping the Commodore 64 - page 231/232 +// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// +// CPU registers that has to be preserved (see [RG64]): none +// -save: +SAVE: rts diff --git a/c64/kernal/f6ed.stop.s b/c64/kernal/f6ed.stop.s index fd0ce804..3f41b20a 100644 --- a/c64/kernal/f6ed.stop.s +++ b/c64/kernal/f6ed.stop.s @@ -1,24 +1,24 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 301 -;; - [CM64] Compute's Mapping the Commodore 64 - page 232 -;; -;; CPU registers that has to be preserved (see [RG64]): .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 301 +// - [CM64] Compute's Mapping the Commodore 64 - page 232 +// +// CPU registers that has to be preserved (see [RG64]): .Y +// -stop: - ;; Bit 7 of STKEY contains the state of the STOP key - ;; (Compute's Mapping the 64, p27) +STOP: + // Bit 7 of STKEY contains the state of the STOP key + // (Compute's Mapping the 64, p27) - ;; BASIC checks carry flag to indicate STOP or not + // BASIC checks carry flag to indicate STOP or not lda STKEY bpl stop_pressed - ;; By trial and error, we know that Z + C = BREAK - ;; and that neither should be set otherwise - lda #$ff + // By trial and error, we know that Z + C = BREAK + // and that neither should be set otherwise + lda #$FF clc rts diff --git a/c64/kernal/fd15.vector.s b/c64/kernal/fd15.vector.s index c5ed62ba..eaad0ece 100644 --- a/c64/kernal/fd15.vector.s +++ b/c64/kernal/fd15.vector.s @@ -1,70 +1,64 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR) -;; - [CM64] Compute's Mapping the Commodore 64 - page 237 -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR) +// - [CM64] Compute's Mapping the Commodore 64 - page 237 +// +// CPU registers that has to be preserved (see [RG64]): none +// -restor: +RESTOR: - clc ;; clear carry - for writing to system table + clc // clear carry - for writing to system table ldx #vector_defaults - ;; FALLTHROUGH + // FALLTHROUGH -vector: +VECTOR: -.scope + // Temporary storage location - checked on real C64 that this is the + // address originally used; after calling VECTOR and checking zero page + // area afterwards, the address could be found there + .label _caller_arr_ptr = MEMUS - ;; Temporary storage location - checked on real C64 that this is the - ;; address originally used; after calling VECTOR and checking zero page - ;; area afterwards, the address could be found there - .alias _caller_arr_ptr MEMUS - - ;; According to 'Compute's Mapping the Commodore 64' page 237, - ;; the CBM implementation does not disable IRQs - yet, the - ;; 'C64 Programmers Reference Guide' does not contain such - ;; warning and does not mention any preparations needed, so... - ;; better safe than sorry, disable the IRQ for the duration - ;; of vector manipulation + // According to 'Compute's Mapping the Commodore 64' page 237, + // the CBM implementation does not disable IRQs - yet, the + // 'C64 Programmers Reference Guide' does not contain such + // warning and does not mention any preparations needed, so... + // better safe than sorry, disable the IRQ for the duration + // of vector manipulation php cli - ;; Prepare the user data pointer - strange order to reduce risk - ;; of potential similarity to the original routine + // Prepare the user data pointer - strange order to reduce risk + // of potential similarity to the original routine sty _caller_arr_ptr + 1 stx _caller_arr_ptr + 0 - ;; Select routine variant - store or restore vectors + // Select routine variant - store or restore vectors ldy #$1F bcc vector_restore - ;; FALLTHROUGH + // FALLTHROUGH vector_store: -* lda CINV, y sta (_caller_arr_ptr), y dey - bpl - + bpl vector_store - ;; Restore status register (IRQ) before return + // Restore status register (IRQ) before return plp rts vector_restore: -* lda (_caller_arr_ptr), y sta CINV, y dey - bpl - + bpl vector_restore - ;; Restore status register (IRQ) before return + // Restore status register (IRQ) before return plp rts - -.scend diff --git a/c64/kernal/fda3.ioinit.s b/c64/kernal/fda3.ioinit.s index 961ffdae..c9fef15b 100644 --- a/c64/kernal/fda3.ioinit.s +++ b/c64/kernal/fda3.ioinit.s @@ -1,34 +1,34 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 285 -;; - [CM64] Compute's Mapping the Commodore 64 - page 238 -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 285 +// - [CM64] Compute's Mapping the Commodore 64 - page 238 +// +// CPU registers that has to be preserved (see [RG64]): none +// -ioinit: +IOINIT: - ; Set $00/$01 port mode and value - ; We want BASIC and KERNAL ROMs mapped, and datasette motor off - ; (https://www.c64-wiki.com/wiki/Zeropage) - ;; XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01 - ;; after. https://sourceforge.net/p/vice-emu/bugs/1057/ + // Set $00/$01 port mode and value + // We want BASIC and KERNAL ROMs mapped, and datasette motor off + // (https://www.c64-wiki.com/wiki/Zeropage) + // XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01 + // after. https://sourceforge.net/p/vice-emu/bugs/1057/ lda #$27 ldx #$2F sta CPU_R6510 stx CPU_D6510 - ;; Silence the SID chips under common addresses + // Silence the SID chips under common addresses ldy #$00 -* - ;; SIDs under $D4xx +!: + // SIDs under $D4xx lda SID_SIGVOL, Y and #$F0 sta SID_SIGVOL, Y - ;; SIDs under $D5xx + // SIDs under $D5xx lda SID_SIGVOL + $100, Y and #$F0 sta SID_SIGVOL + $100, Y @@ -36,24 +36,24 @@ ioinit: clc adc #$20 tay - bne - + bne !- - ;; XXX: calibrate TOD for both CIA's, see here: https://codebase64.org/doku.php?id=base:efficient_tod_initialisation + // XXX: calibrate TOD for both CIA's, see here: https://codebase64.org/doku.php?id=base:efficient_tod_initialisation - ;; Enable CIA1 IRQ and ~50Hz timer (https://csdb.dk/forums/?roomid=11&topicid=69037) + // Enable CIA1 IRQ and ~50Hz timer (https://csdb.dk/forums/?roomid=11&topicid=69037) lda #$7F - sta CIA1_ICR ; disable all + sta CIA1_ICR // disable all - ;; Set timer interval to ~1/60th of a second + // Set timer interval to ~1/60th of a second - ;; (This value was calculated by running a custom IRQ handler on a C64 - ;; with original KERNAL, and writing the values of $DC04/5 to the screen - ;; in the IRQ handler to see roughly what value the timers must be set to) - ;; ldy #<16380 - ;; ldx #>16380 + // (This value was calculated by running a custom IRQ handler on a C64 + // with original KERNAL, and writing the values of $DC04/5 to the screen + // in the IRQ handler to see roughly what value the timers must be set to) + // ldy #<16380 + // ldx #>16380 - ;; PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), - ;; is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles + // PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), + // is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles ldy #<16421 ldx #>16421 @@ -61,19 +61,19 @@ ioinit: sty CIA1_TIMALO stx CIA1_TIMAHI - ;; Enable timer interrupt + // Enable timer interrupt lda #$81 sta CIA1_ICR - ;; Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts) + // Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts) lda #$11 sta CIA1_CRA lda CIA1_ICR - ;; Set DDR on CIA2 for IEC bus, VIC-II banking + // Set DDR on CIA2 for IEC bus, VIC-II banking lda #$3B sta CIA2_DDRA - ;; Set IEC bus to its initial idle state + // Set IEC bus to its initial idle state jmp iec_set_idle diff --git a/c64/kernal/ff5b.cint.jmp.s b/c64/kernal/ff5b.cint.jmp.s index b5497eca..d692928f 100644 --- a/c64/kernal/ff5b.cint.jmp.s +++ b/c64/kernal/ff5b.cint.jmp.s @@ -1,6 +1,6 @@ -;; Our implementation is longer than the original one, -;; placing it here would cause a collision with OPEN +// Our implementation is longer than the original one, +// placing it here would cause a collision with OPEN -cint: +CINT: jmp cint_real diff --git a/c64/kernal/ff80.kernal_revision.s b/c64/kernal/ff80.kernal_revision.s index 7cadcbec..ff387fe3 100644 --- a/c64/kernal/ff80.kernal_revision.s +++ b/c64/kernal/ff80.kernal_revision.s @@ -1,31 +1,63 @@ -;; -;; This byte identifies Kernal revision. Sources: -;; - [CM64] Compute's Mapping the Commodore 64 (page 242/243) -;; - [MM] Marko Mäkelä article, http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt -;; - [VICE] Checked with ROMs included in VICE emulator -;; -;; IDEA: put here a value, that is different from any version currently known, as -;; a warning that this is not a Commodore Kernal. Currently known numbers for C64 are: -;; -;; - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2 -;; - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3 -;; - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64 -;; - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64 -;; - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1 -;; -;; Values from unofficial ROMs: -;; - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE] -;; -;; Values from other Commodore machines: -;; C128: -;; - $01 - see https://www.pagetable.com/?p=1058 -;; - $02 - unreleased updated ROM, see https://www.pagetable.com/?p=1058 -;; -;; XXX check more unofficial C64 ROMs (JiffyDOS, DolphinDOS, etc.) and other machines -;; VIC-20, PET, CBM II, 264 series, C65 prototypes, other sources for C128 ROMs -;; - +// +// This byte (hex $FF80, dec 65408) identifies Kernal revision on several machines. Although not all +// of the, used it for versioning purpose, here is the list of all the values I could find. Sources: +// - [CM64] Compute's Mapping the Commodore 64 (page 242/243) +// - [MM] Marko Mäkelä article, http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt +// - [VICE] Checked with ROMs included in VICE emulator +// - [XEMU] Checked with ROMs retrieved by XEMU emulator +// +// IDEA: put here a value, that is different from any version currently known, as +// a warning that this is not a Commodore Kernal or anything already known. +// +// C64 - values from the official ROMs: +// - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2 +// - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3 +// - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64 +// - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64 +// - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1 +// +// C64 - values from unofficial 3rd party ROMs: +// - $00 - Turbo Trans, Turbo Access, Turbo Process +// - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE], +// DolphinDOS 2.0, JiffyDOS 6.01, EXOS V3/4, +// Datel Mercury V3 US, Datel DOS-ROM V1.2, Datel Turbo ROM II V3.2+, +// Turbo Process US, +// burst CIA 1/2 Kernal by Albert, SD2IEC Kernal 1.0/2.0/2.1/2.2 by Claus +// - $4A - S-JiffyDOS +// - $53 - Professional DOS V1, SpeedDOS Plus 2.7 +// - $C3 - Cockroach Turbo ROM V1 +// +// PET: +// - $40 - [VICE] PET 2001-8N +// - $A7 - [VICE] PET 30XX +// - $AA - [VICE] PET 40XX, PET 80XX, SuperPET +// +// CBM II: +// - $E0 - [VICE] 5x0, 6x0, 7x0 models +// +// VIC-20: +// - $16 - [VICE] all models, also VIC-20 JiffyDOS PAL/NTSC +// +// 264 family: +// - $01 - [VICE] 364 +// - $05 - [VICE] C16, C116, Plus/4 +// - $06 - (unofficial) JiffyDOS NTSC +// - $81 - [VICE] 232 +// - $86 - (unofficial) JiffyDOS PAL +// +// C128: +// - $01 - see https://www.pagetable.com/?p=1058 +// - $02 - unreleased updated ROM, see https://www.pagetable.com/?p=1058 +// +// Commodore prototypes: +// - $04 - [XEMU] 64 mode ROM of the C65 prototype, ROM 910111 +// - $FF - [XEMU] C65 native mode, ROM 910111 +// - $FF - [XEMU] Commodore LCD +// +// Non-Commodore machines: +// - $FF - Commander X16 (emulator r28) +// kernal_revision: - .byte $FF + .byte $FF // XXX possibly change this value (current candidate: $F0), $FF conflicts with other machines diff --git a/c64/kernal/fffa.s b/c64/kernal/fffa.s index 7218f8fb..d39f0f53 100644 --- a/c64/kernal/fffa.s +++ b/c64/kernal/fffa.s @@ -1,4 +1,4 @@ -; $FFFA - CPU NMI Hanlder -; Uncontrovertial as this is also a CPU requirement. +// $FFFA - CPU NMI Hanlder +// Uncontrovertial as this is also a CPU requirement. .word nmi_handler diff --git a/c64/kernal/fffc.s b/c64/kernal/fffc.s index e494873d..eb4f1ba8 100644 --- a/c64/kernal/fffc.s +++ b/c64/kernal/fffc.s @@ -1,4 +1,4 @@ -; $FFFC - CPU Reset Vector -; Uncontrovertial, as it is a CPU requirement, and nothing else. +// $FFFC - CPU Reset Vector +// Uncontrovertial, as it is a CPU requirement, and nothing else. .word reset_entry diff --git a/c64/kernal/fffe.s b/c64/kernal/fffe.s index 8cacf712..2a892889 100644 --- a/c64/kernal/fffe.s +++ b/c64/kernal/fffe.s @@ -1,5 +1,5 @@ -; $FFFE - CPU IRQ Vector. -; This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point -; it to whatever IRQ routine we make. +// $FFFE - CPU IRQ Vector. +// This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point +// it to whatever IRQ routine we make. .word irq_handler diff --git a/c64/kernal/findfls.s b/c64/kernal/findfls.s index 403139e0..f9cefadd 100644 --- a/c64/kernal/findfls.s +++ b/c64/kernal/findfls.s @@ -1,18 +1,18 @@ -;; Just a helper routines +// Just a helper routines -;; Find the LAT / SAT / FAT entry index where LAT corresponds to A, returns index in Y -;; Carry flag set means not found +// Find the LAT / SAT / FAT entry index where LAT corresponds to A, returns index in Y +// Carry flag set means not found find_fls: ldy LDTND - beq find_fls_not_found ; table empty -* + beq find_fls_not_found // table empty +!: dey - bmi find_fls_not_found ; no more entries + bmi find_fls_not_found // no more entries cmp LAT, y - bne - ; does not match, try the next one + bne !- // does not match, try the next one clc rts diff --git a/c64/kernal/home_cursor.s b/c64/kernal/home_cursor.s index eec755ee..0e833d94 100644 --- a/c64/kernal/home_cursor.s +++ b/c64/kernal/home_cursor.s @@ -1,5 +1,5 @@ - ;; Home the cursor - ;; (Compute's Mapping the 64 p216) +// Home the cursor +// (Compute's Mapping the 64 p216) home_cursor: diff --git a/c64/kernal/iec/iec_check_devnum.s b/c64/kernal/iec/iec_check_devnum.s index e5e354fa..0071392b 100644 --- a/c64/kernal/iec/iec_check_devnum.s +++ b/c64/kernal/iec/iec_check_devnum.s @@ -1,22 +1,22 @@ -;; -;; Checks whether device number (in .A) is a correct IEC device number -;; -;; Preserves .A, .X and .Y -;; +// +// Checks whether device number (in .A) is a correct IEC device number +// +// Preserves .A, .X and .Y +// iec_check_devnum: - ;; 0, 1, 2, or 3 are illegal - reserved for non-IEC devices on Commodore + // 0, 1, 2, or 3 are illegal - reserved for non-IEC devices on Commodore cmp #$04 - bcs + - ;; FALLTROUGH + bcs !+ + // FALLTROUGH iec_check_devnum_failed: - sec ; indicate non-IEC device + sec // indicate non-IEC device rts -* - ;; 31 and above are illegal too, due to IEC command encoding scheme, - ;; see https://www.pagetable.com/?p=1031 +!: + // 31 and above are illegal too, due to IEC command encoding scheme, + // see https://www.pagetable.com/?p=1031 cmp #$1F bcs iec_check_devnum_failed - ;; Carry is clear here - indicates IEC device + // Carry is clear here - indicates IEC device rts diff --git a/c64/kernal/iec/iec_cmd_close.s b/c64/kernal/iec/iec_cmd_close.s index 60c30a96..114cf0e4 100644 --- a/c64/kernal/iec/iec_cmd_close.s +++ b/c64/kernal/iec/iec_cmd_close.s @@ -1,16 +1,16 @@ -;; -;; Kernal internal IEC routine -;; -;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc -;; +// +// Kernal internal IEC routine +// +// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc +// iec_cmd_close: jsr iec_check_channel_openclose - bcc + + bcc !+ jmp kernalerror_FILE_NOT_INPUT -* +!: ora #$E0 jmp common_open_close_unlsn_second diff --git a/c64/kernal/iec/iec_cmd_open.s b/c64/kernal/iec/iec_cmd_open.s index aa23a2c5..1d6389ab 100644 --- a/c64/kernal/iec/iec_cmd_open.s +++ b/c64/kernal/iec/iec_cmd_open.s @@ -1,42 +1,42 @@ -;; -;; Kernal internal IEC routine -;; -;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc -;; +// +// Kernal internal IEC routine +// +// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc +// -iec_cmd_open: ; similar to TKSA, but without turnaround +iec_cmd_open: // similar to TKSA, but without turnaround jsr iec_check_channel_openclose - bcc + + bcc !+ jmp kernalerror_FILE_NOT_INPUT -* +!: ora #$F0 - ;; FALLTROUGH + // FALLTROUGH -common_open_close_unlsn_second: ; common part of several commands +common_open_close_unlsn_second: // common part of several commands sta IEC_TMP2 jsr iec_tx_command - bcs + ; branch if error + bcs !+ // branch if error jmp iec_tx_command_finalize -* +!: rts iec_check_channel_openclose: - ;; Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031), - ;; allowed channels are 0-15; report error if out of range + // Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031), + // allowed channels are 0-15; report error if out of range cmp #$10 - bcc + - ;; Workaround to allow reading executable files and disk directory - ;; using OPEN routine - see https://www.pagetable.com/?p=273 for - ;; example usage + bcc !+ + // Workaround to allow reading executable files and disk directory + // using OPEN routine - see https://www.pagetable.com/?p=273 for + // example usage cmp #$60 - beq + - sec ; mark unsuitable channel number + beq !+ + sec // mark unsuitable channel number rts -* - clc ; mark suitable channel number +!: + clc // mark suitable channel number rts diff --git a/c64/kernal/iec/iec_pull_atn_clk_release_data.s b/c64/kernal/iec/iec_pull_atn_clk_release_data.s index 7d00da80..62da6f12 100644 --- a/c64/kernal/iec/iec_pull_atn_clk_release_data.s +++ b/c64/kernal/iec/iec_pull_atn_clk_release_data.s @@ -1,15 +1,15 @@ iec_pull_atn_clk_release_data: - ;; Pulled CLK = DATA considered invalid; for extra robustness on non-emulated - ;; hardware give some lines few more cycles to stabilize; see page 10 of - ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // Pulled CLK = DATA considered invalid; for extra robustness on non-emulated + // hardware give some lines few more cycles to stabilize; see page 10 of + // http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf lda CIA2_PRA - ora #BIT_CIA2_PRA_ATN_OUT ; pull + ora #BIT_CIA2_PRA_ATN_OUT // pull sta CIA2_PRA - ora #BIT_CIA2_PRA_CLK_OUT ; pull + ora #BIT_CIA2_PRA_CLK_OUT // pull sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_DAT_OUT ; release + and #$FF - BIT_CIA2_PRA_DAT_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_pull_clk_release_data.s b/c64/kernal/iec/iec_pull_clk_release_data.s index 38be0f89..2b1a58f8 100644 --- a/c64/kernal/iec/iec_pull_clk_release_data.s +++ b/c64/kernal/iec/iec_pull_clk_release_data.s @@ -1,13 +1,13 @@ iec_pull_clk_release_data: - ;; Pulled CLK = DATA considered invalid; for extra robustness on non-emulated - ;; hardware give some lines few more cycles to stabilize; see page 10 of - ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // Pulled CLK = DATA considered invalid; for extra robustness on non-emulated + // hardware give some lines few more cycles to stabilize; see page 10 of + // http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf lda CIA2_PRA - ora #BIT_CIA2_PRA_CLK_OUT ; pull + ora #BIT_CIA2_PRA_CLK_OUT // pull sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_DAT_OUT ; release + and #$FF - BIT_CIA2_PRA_DAT_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_pull_clk_release_data_oneshot.s b/c64/kernal/iec/iec_pull_clk_release_data_oneshot.s index 78d40472..b2a80988 100644 --- a/c64/kernal/iec/iec_pull_clk_release_data_oneshot.s +++ b/c64/kernal/iec/iec_pull_clk_release_data_oneshot.s @@ -2,7 +2,7 @@ iec_pull_clk_release_data_oneshot: lda CIA2_PRA - ora #BIT_CIA2_PRA_CLK_OUT ; pull - and #$FF - BIT_CIA2_PRA_DAT_OUT ; release + ora #BIT_CIA2_PRA_CLK_OUT // pull + and #$FF - BIT_CIA2_PRA_DAT_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_pull_data_release_atn_clk.s b/c64/kernal/iec/iec_pull_data_release_atn_clk.s index 14e0e236..f7c71da4 100644 --- a/c64/kernal/iec/iec_pull_data_release_atn_clk.s +++ b/c64/kernal/iec/iec_pull_data_release_atn_clk.s @@ -1,15 +1,15 @@ iec_pull_data_release_atn_clk: - ;; Released CLK = DATA considered valid; for extra robustness on non-emulated - ;; hardware give some lines few more cycles to stabilize; see page 10 of - ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // Released CLK = DATA considered valid; for extra robustness on non-emulated + // hardware give some lines few more cycles to stabilize; see page 10 of + // http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf lda CIA2_PRA - ora #BIT_CIA2_PRA_DAT_OUT ; pull + ora #BIT_CIA2_PRA_DAT_OUT // pull sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_CLK_OUT ; release + and #$FF - BIT_CIA2_PRA_CLK_OUT // release sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_ATN_OUT ; release + and #$FF - BIT_CIA2_PRA_ATN_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_release_atn.s b/c64/kernal/iec/iec_release_atn.s index 2aef8984..d7493aa0 100644 --- a/c64/kernal/iec/iec_release_atn.s +++ b/c64/kernal/iec/iec_release_atn.s @@ -2,7 +2,7 @@ iec_release_atn: lda CIA2_PRA - and #$FF - BIT_CIA2_PRA_ATN_OUT ; release + and #$FF - BIT_CIA2_PRA_ATN_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_release_atn_clk_data.s b/c64/kernal/iec/iec_release_atn_clk_data.s index 904ee13f..07f5c4da 100644 --- a/c64/kernal/iec/iec_release_atn_clk_data.s +++ b/c64/kernal/iec/iec_release_atn_clk_data.s @@ -1,16 +1,16 @@ iec_release_atn_clk_data: - ;; Released CLK = DATA considered valid; for extra robustness on non-emulated - ;; hardware give some lines few more cycles to stabilize; see page 10 of - ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // Released CLK = DATA considered valid; for extra robustness on non-emulated + // hardware give some lines few more cycles to stabilize; see page 10 of + // http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf lda CIA2_PRA - and #$FF - BIT_CIA2_PRA_ATN_OUT ; release + and #$FF - BIT_CIA2_PRA_ATN_OUT // release sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_DAT_OUT ; release + and #$FF - BIT_CIA2_PRA_DAT_OUT // release sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_CLK_OUT ; release + and #$FF - BIT_CIA2_PRA_CLK_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_release_clk_data.s b/c64/kernal/iec/iec_release_clk_data.s index f48daa6c..83af42aa 100644 --- a/c64/kernal/iec/iec_release_clk_data.s +++ b/c64/kernal/iec/iec_release_clk_data.s @@ -1,13 +1,13 @@ iec_release_clk_data: - ;; Released CLK = DATA considered valid; for extra robustness on non-emulated - ;; hardware give some lines few more cycles to stabilize; see page 10 of - ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // Released CLK = DATA considered valid; for extra robustness on non-emulated + // hardware give some lines few more cycles to stabilize; see page 10 of + // http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf lda CIA2_PRA - and #$FF - BIT_CIA2_PRA_DAT_OUT ; release + and #$FF - BIT_CIA2_PRA_DAT_OUT // release sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_CLK_OUT ; release + and #$FF - BIT_CIA2_PRA_CLK_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_release_clk_pull_data.s b/c64/kernal/iec/iec_release_clk_pull_data.s index 9f252ed3..359c02f3 100644 --- a/c64/kernal/iec/iec_release_clk_pull_data.s +++ b/c64/kernal/iec/iec_release_clk_pull_data.s @@ -1,13 +1,13 @@ iec_release_clk_pull_data: - ;; Released CLK = DATA considered valid; for extra robustness on non-emulated - ;; hardware give some lines few more cycles to stabilize; see page 10 of - ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // Released CLK = DATA considered valid; for extra robustness on non-emulated + // hardware give some lines few more cycles to stabilize; see page 10 of + // http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf lda CIA2_PRA - ora #BIT_CIA2_PRA_DAT_OUT ; pull + ora #BIT_CIA2_PRA_DAT_OUT // pull sta CIA2_PRA - and #$FF - BIT_CIA2_PRA_CLK_OUT ; release + and #$FF - BIT_CIA2_PRA_CLK_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_return.s b/c64/kernal/iec/iec_return.s index a89a1336..149f781f 100644 --- a/c64/kernal/iec/iec_return.s +++ b/c64/kernal/iec/iec_return.s @@ -1,38 +1,38 @@ -;; -;; Helper routines to return with error/success -;; -;; All of them restore X/Y registers from stack, -;; they take care about Carry flag, -;; error return reeset IEC line to default state, -;; take care about .A and IOSTATUS -;; +// +// Helper routines to return with error/success +// +// All of them restore X/Y registers from stack, +// they take care about Carry flag, +// error return reeset IEC line to default state, +// take care about .A and IOSTATUS +// iec_return_success: - ;; BSOUR is certainly not valid anymore + // BSOUR is certainly not valid anymore lda #$00 sta C3PO - ;; Restore registers + // Restore registers pla tay pla tax - ;; Report success + // Report success clc rts iec_return_DEVICE_NOT_FOUND: - ;; Set IEC line to normal idle state + // Set IEC line to normal idle state jsr iec_set_idle - ;; BSOUR is certainly not valid anymore + // BSOUR is certainly not valid anymore lda #$00 sta C3PO - ;; Restore registers + // Restore registers pla tay pla tax - ;; Report error + // Report error jmp kernalerror_DEVICE_NOT_FOUND diff --git a/c64/kernal/iec/iec_rx_byte.s b/c64/kernal/iec/iec_rx_byte.s index c9a3b501..f0f17915 100644 --- a/c64/kernal/iec/iec_rx_byte.s +++ b/c64/kernal/iec/iec_rx_byte.s @@ -1,141 +1,141 @@ -;; Receive a byte from the IEC bus. -;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc, -;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 11) -;; -;; Preserves .X and .Y registers +// Receive a byte from the IEC bus. +// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc, +// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 11) +// +// Preserves .X and .Y registers iec_rx_byte: - ;; Store .X and .Y on the stack - preserve them + // Store .X and .Y on the stack - preserve them txa pha tya pha - ;; Timing is critical here - execute on disabled IRQs + // Timing is critical here - execute on disabled IRQs php sei - ;; First, we wait for the talker to release the CLK line + // First, we wait for the talker to release the CLK line jsr iec_wait_for_clk_release - ;; We then release the DATA to signal we are ready - ;; We can use this routine, since we weren't pulling CLK anyway + // We then release the DATA to signal we are ready + // We can use this routine, since we weren't pulling CLK anyway jsr iec_release_clk_data - ;; Wait till data line is released (someone else might be holding it) + // Wait till data line is released (someone else might be holding it) jsr iec_wait_for_data_release - ;; Wait for talker to pull CLK. - ;; If over 200 usec (205 cycles on NTSC machine) , then it is EOI. - ;; Loop iteraction takes 13 cycles, 17 full iterations are enough + // Wait for talker to pull CLK. + // If over 200 usec (205 cycles on NTSC machine) , then it is EOI. + // Loop iteraction takes 13 cycles, 17 full iterations are enough - ldx #$11 ; 2 cycles + ldx #$11 // 2 cycles iec_rx_clk_wait1: - lda CIA2_PRA ; 4 cycles - rol ; 2 cycles, to put CLK in as the last bit - bpl iec_rx_not_eoi ; 2 cycles if not jumped - dex ; 2 cycles - bne iec_rx_clk_wait1 ; 3 cycles if jumped + lda CIA2_PRA // 4 cycles + rol // 2 cycles, to put CLK in as the last bit + bpl iec_rx_not_eoi // 2 cycles if not jumped + dex // 2 cycles + bne iec_rx_clk_wait1 // 3 cycles if jumped - ;; Timeout - either this is the last byte of stream, or the stream is empty at all. - ;; Mark end of stream in IOSTATUS - jsr kernalstatus_EOI + // Timeout - either this is the last byte of stream, or the stream is empty at all. + // Mark end of stream in IOSTATUS + jsr kernalstatus_EOI iec_rx_not_empty: - ;; Pull data for 60 usec to confirm it + // Pull data for 60 usec to confirm it jsr iec_release_clk_pull_data jsr iec_wait60us jsr iec_release_clk_data iec_rx_not_eoi: - ;; Latch input bits in on rising edge of CLK, eight times for eight bits. + // Latch input bits in on rising edge of CLK, eight times for eight bits. ldx #7 - ;; Get empty byte to load into. + // Get empty byte to load into. lda #$00 pha iec_rx_bit_loop: - ;; Wait for CLK to release + // Wait for CLK to release jsr iec_wait_for_clk_release - ;; (we do this implicitly below, with a tighter routine, - ;; so that we don't have timing problems, as the requirements - ;; are quite tight. Basically we need to read the clock and data - ;; bit from the same byte read. + // (we do this implicitly below, with a tighter routine, + // so that we don't have timing problems, as the requirements + // are quite tight. Basically we need to read the clock and data + // bit from the same byte read. - ;; DATA now has the next bit, but inverted (well, except that it turns out not to be). - ;; DATA is in bit 7, which is a bit annoying. - ;; But we can clock it out with a ROL instruction - ;; so that it is in C. We can then ROR it into the - ;; partial data byte. - ;; We use ROR so that we shift in from the top, so that - ;; the first bit we shift in ends up in bit 0 after all - ;; 8 bits have been read. - ;; ODD: For some reason we don't need to invert the - ;; received bits. This is weird, because we invert them - ;; on the way out, and everything in the protocol seems - ;; to indicate that we sould do so. But experimentation - ;; has confirmed the bits don't need inversion on reception. + // DATA now has the next bit, but inverted (well, except that it turns out not to be). + // DATA is in bit 7, which is a bit annoying. + // But we can clock it out with a ROL instruction + // so that it is in C. We can then ROR it into the + // partial data byte. + // We use ROR so that we shift in from the top, so that + // the first bit we shift in ends up in bit 0 after all + // 8 bits have been read. + // ODD: For some reason we don't need to invert the + // received bits. This is weird, because we invert them + // on the way out, and everything in the protocol seems + // to indicate that we sould do so. But experimentation + // has confirmed the bits don't need inversion on reception. - ;; Move data bit into C flag, and loop until bit 6 clears - ;; i.e., the clock has been released. + // Move data bit into C flag, and loop until bit 6 clears + // i.e., the clock has been released. -* lda CIA2_PRA +!: lda CIA2_PRA rol - bpl - + bpl !- - ;; Pull it into the data byte + // Pull it into the data byte pla ror pha - ;; Wait for CLK to be pulled again, over 300 usec (307 cycles on NTSC) - ;; consider this a timeout - ldy #$19 ; 2 cycles + // Wait for CLK to be pulled again, over 300 usec (307 cycles on NTSC) + // consider this a timeout + ldy #$19 // 2 cycles iec_rx_clk_wait2: - lda CIA2_PRA ; 4 cycles - rol ; 2 cycles, to put CLK in as the last bit - bpl + ; 2 cycles if not jumped - dey ; 2 cycles - bne iec_rx_clk_wait2 ; 3 cycles if jumped + lda CIA2_PRA // 4 cycles + rol // 2 cycles, to put CLK in as the last bit + bpl !+ // 2 cycles if not jumped + dey // 2 cycles + bne iec_rx_clk_wait2 // 3 cycles if jumped - ;; Timeout + // Timeout jsr kernalstatus_EOI pla plp - ;; Restore registers + // Restore registers pla tay pla tax - sec ; XXX confirm that sec is really a way to report timeout here + sec // XXX confirm that sec is really a way to report timeout here rts -* - ;; More bits? +!: + // More bits? dex bpl iec_rx_bit_loop - ;; Then we must within 1000 usec acknowledge the frame by - ;; pulling DATA. At this point, CLK is pulled by the - ;; talker and DATA by us, i.e., we are ready to receive - ;; the next byte. (p11). + // Then we must within 1000 usec acknowledge the frame by + // pulling DATA. At this point, CLK is pulled by the + // talker and DATA by us, i.e., we are ready to receive + // the next byte. (p11). jsr iec_release_clk_pull_data - ;; Retreive the received byte + // Retreive the received byte pla - ;; Return no-error + // Return no-error plp - ;; Restore registers - sta IEC_TMP2 ; $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html + // Restore registers + sta IEC_TMP2 // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html pla tay pla diff --git a/c64/kernal/iec/iec_set_idle.s b/c64/kernal/iec/iec_set_idle.s index 1604306d..9b0015d0 100644 --- a/c64/kernal/iec/iec_set_idle.s +++ b/c64/kernal/iec/iec_set_idle.s @@ -1,7 +1,7 @@ iec_set_idle: lda CIA2_PRA - ora #BIT_CIA2_PRA_CLK_OUT ; pull - and #$FF - BIT_CIA2_PRA_DAT_OUT - BIT_CIA2_PRA_ATN_OUT ; release + ora #BIT_CIA2_PRA_CLK_OUT // pull + and #$FF - BIT_CIA2_PRA_DAT_OUT - BIT_CIA2_PRA_ATN_OUT // release sta CIA2_PRA rts diff --git a/c64/kernal/iec/iec_turnaround_to_listen.s b/c64/kernal/iec/iec_turnaround_to_listen.s index 0e66047a..fb4cd078 100644 --- a/c64/kernal/iec/iec_turnaround_to_listen.s +++ b/c64/kernal/iec/iec_turnaround_to_listen.s @@ -1,37 +1,37 @@ - ;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf - ;; pages 7--8. - ;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc +// According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// pages 7--8. +// See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc iec_turnaround_to_listen: - ;; Store .X and .Y on the stack - preserve them + // Store .X and .Y on the stack - preserve them txa pha tya pha - ;; Timing is critical here - execute on disabled IRQs + // Timing is critical here - execute on disabled IRQs php sei - ;; Pull DATA, release CLK and ATN (we are not sending commands) + // Pull DATA, release CLK and ATN (we are not sending commands) jsr iec_pull_data_release_atn_clk - ;; Wait for clock line to be pulled by the drive - ldx #$FF ; XXX should we really use that high number? -* + // Wait for clock line to be pulled by the drive + ldx #$FF // XXX should we really use that high number? +!: lda CIA2_PRA - rol ; to put BIT_CIA2_PRA_CLK_IN as the last (sign) bit - bpl + + rol // to put BIT_CIA2_PRA_CLK_IN as the last (sign) bit + bpl !+ dex - bne - + bne !- - ;; Timeout - XXX what errors do original Kernal report? + // Timeout - XXX what errors do original Kernal report? plp jmp iec_return_DEVICE_NOT_FOUND - ;; CLK is pulled by the device, OK -* + // CLK is pulled by the device, OK +!: plp jmp iec_return_success diff --git a/c64/kernal/iec/iec_turnaround_to_talk.s b/c64/kernal/iec/iec_turnaround_to_talk.s index 666c89e2..f7ea9c9b 100644 --- a/c64/kernal/iec/iec_turnaround_to_talk.s +++ b/c64/kernal/iec/iec_turnaround_to_talk.s @@ -1,27 +1,27 @@ - ;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf - ;; pages 7--8. - ;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc +// According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// pages 7--8. +// See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc iec_turnaround_to_talk: - ;; Store .X and .Y on the stack - preserve them + // Store .X and .Y on the stack - preserve them txa pha tya pha - ;; Timing is critical here - execute on disabled IRQs + // Timing is critical here - execute on disabled IRQs php sei - ;; First make sure both CLK, DATA and ATN are released at our side + // First make sure both CLK, DATA and ATN are released at our side jsr iec_release_atn jsr iec_release_clk_data - ;; Wait till device releases CLK line + // Wait till device releases CLK line jsr iec_wait_for_clk_release - ;; Pull CLK line, it should be held by talker + // Pull CLK line, it should be held by talker jsr iec_pull_clk_release_data plp diff --git a/c64/kernal/iec/iec_tx_byte.s b/c64/kernal/iec/iec_tx_byte.s index 76c12e45..bd561fb9 100644 --- a/c64/kernal/iec/iec_tx_byte.s +++ b/c64/kernal/iec/iec_tx_byte.s @@ -1,96 +1,96 @@ -;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc +// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc -;; Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) -;; Carry flag set = signal EOI -;; -;; Preserves .X and .Y registers +// Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) +// Carry flag set = signal EOI +// +// Preserves .X and .Y registers iec_tx_byte: - ;; Store .X and .Y on the stack - preserve them + // Store .X and .Y on the stack - preserve them txa pha tya pha - ;; Notify all devices that we are going to send a byte - ;; and it is going to be a data byte (released ATN) + // Notify all devices that we are going to send a byte + // and it is going to be a data byte (released ATN) jsr iec_release_atn_clk_data - ;; Common part of iec_tx_byte and iec_tx_command - ;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc - ;; and http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf + // Common part of iec_tx_byte and iec_tx_command + // Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc + // and http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf iec_tx_common: - ;; Timing is critical here - execute on disabled IRQs + // Timing is critical here - execute on disabled IRQs php sei - ;; Wait till all receivers are ready, they should all release DATA + // Wait till all receivers are ready, they should all release DATA jsr iec_wait_for_data_release - bcc + + bcc !+ - ;; At this point a delay 256 usec or more is considered EOI, - ;; receiver should now acknowledge it by pulling data for at least 60 usec - ;; Keep the implementation as simple as possible: data should be released now - ;; so wait until it's pushed and released again + // At this point a delay 256 usec or more is considered EOI, + // receiver should now acknowledge it by pulling data for at least 60 usec + // Keep the implementation as simple as possible: data should be released now + // so wait until it's pushed and released again jsr iec_wait_for_data_pull jsr iec_wait_for_data_release -* - ;; Pull CLK back to indicate that DATA is not valid, keep it for 60us - ;; We can use this routine as we don't hold DATA anyway (and its state doesn't even matter) +!: + // Pull CLK back to indicate that DATA is not valid, keep it for 60us + // We can use this routine as we don't hold DATA anyway (and its state doesn't even matter) jsr iec_pull_clk_release_data_oneshot jsr iec_wait60us - ;; Now, we can start transmission of 8 bits of data + // Now, we can start transmission of 8 bits of data ldx #7 iec_tx_common_sendbit: - ;; Is next bit 0 or 1? + // Is next bit 0 or 1? lda IEC_TMP2 lsr sta IEC_TMP2 - bcs + + bcs !+ - ;; Bit is 0 + // Bit is 0 jsr iec_release_clk_pull_data jmp iec_tx_common_bit_is_sent -* - ;; Bit is 1 +!: + // Bit is 1 jsr iec_release_clk_data iec_tx_common_bit_is_sent: - ;; Wait 20us, so that device(s) can pick DATA + // Wait 20us, so that device(s) can pick DATA jsr iec_wait20us - ;; Pull CLK for 20us again, before sending the next bit - ;; or performing any other action + // Pull CLK for 20us again, before sending the next bit + // or performing any other action jsr iec_pull_clk_release_data_oneshot jsr iec_wait20us - ;; More bits to send? + // More bits to send? dex bpl iec_tx_common_sendbit plp - ;; Give device time to tell if they are busy by pulling DATA - ;; They should do it within 1ms + // Give device time to tell if they are busy by pulling DATA + // They should do it within 1ms ldx #$FF -* lda CIA2_PRA - ;; BPL here is checking that bit 7 clears, - ;; i.e, that the DATA line is pulled by drive - bpl + +!: lda CIA2_PRA + // BPL here is checking that bit 7 clears, + // i.e, that the DATA line is pulled by drive + bpl !+ dex - bne - - bmi + + bne !- + bmi !+ jmp iec_return_DEVICE_NOT_FOUND -* +!: jmp iec_return_success diff --git a/c64/kernal/iec/iec_tx_command.s b/c64/kernal/iec/iec_tx_command.s index 2332be44..6965d1d0 100644 --- a/c64/kernal/iec/iec_tx_command.s +++ b/c64/kernal/iec/iec_tx_command.s @@ -1,40 +1,40 @@ -;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc +// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc -;; Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) -;; Carry flag set = signal EOI -;; -;; Preserves .X and .Y registers +// Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) +// Carry flag set = signal EOI +// +// Preserves .X and .Y registers iec_tx_command: - ;; Store .X and .Y on the stack - preserve them + // Store .X and .Y on the stack - preserve them txa pha tya pha - ;; Notify all devices that we are going to send a byte - ;; and it is going to be a command (pulled ATN) + // Notify all devices that we are going to send a byte + // and it is going to be a command (pulled ATN) jsr iec_pull_atn_clk_release_data - ;; Give devices time to respond (response is mandatory!) by pulling DATA + // Give devices time to respond (response is mandatory!) by pulling DATA jsr iec_wait1ms - lda CIA2_PRA ; pulled DATA = highest bit 0 = 'plus' - bpl + + lda CIA2_PRA // pulled DATA = highest bit 0 = 'plus' + bpl !+ jmp iec_return_DEVICE_NOT_FOUND -* - ;; At least one device responded, but they are still allowed to stall - ;; (can be busy processing something), we have to wait till they are all - ;; ready (or bored with DOS attack...) - ;; Release back CLK, keep DATA released - to ask devices for status. +!: + // At least one device responded, but they are still allowed to stall + // (can be busy processing something), we have to wait till they are all + // ready (or bored with DOS attack...) + // Release back CLK, keep DATA released - to ask devices for status. jsr iec_release_clk_data - ;; Common part of iec_txbyte and iec_tx_common - waits for devices - ;; and transmits a byte + // Common part of iec_txbyte and iec_tx_common - waits for devices + // and transmits a byte - clc ; Carry flag set is used for EOI mark + clc // Carry flag set is used for EOI mark jmp iec_tx_common diff --git a/c64/kernal/iec/iec_tx_command_finalize.s b/c64/kernal/iec/iec_tx_command_finalize.s index e0ad0c35..6f11ea03 100644 --- a/c64/kernal/iec/iec_tx_command_finalize.s +++ b/c64/kernal/iec/iec_tx_command_finalize.s @@ -1,18 +1,18 @@ -;; Routine to finalize some IEC commands - which do not end in turnaround and are not followed by others -;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc +// Routine to finalize some IEC commands - which do not end in turnaround and are not followed by others +// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc iec_tx_command_finalize: - ;; Store .X and .Y on the stack - preserve them + // Store .X and .Y on the stack - preserve them txa pha tya pha - ;; Give device some time to complete command reception, release ATN, - ;; give it some time again before (possible) next command + // Give device some time to complete command reception, release ATN, + // give it some time again before (possible) next command jsr iec_wait20us jsr iec_set_idle jsr iec_wait20us diff --git a/c64/kernal/iec/iec_tx_flush.s b/c64/kernal/iec/iec_tx_flush.s index 95395f77..d6db894f 100644 --- a/c64/kernal/iec/iec_tx_flush.s +++ b/c64/kernal/iec/iec_tx_flush.s @@ -1,15 +1,15 @@ -;; Flush the IEC output buffer (if not empty) - send byte with EOI -;; -;; Preserves .X, .Y and .A registers +// Flush the IEC output buffer (if not empty) - send byte with EOI +// +// Preserves .X, .Y and .A registers iec_tx_flush: pha lda C3PO - beq + - sec ; send it with EOI - jsr iec_tx_byte ; send the command regardless of the status -* + beq !+ + sec // send it with EOI + jsr iec_tx_byte // send the command regardless of the status +!: pla rts diff --git a/c64/kernal/iec/iec_wait1ms.s b/c64/kernal/iec/iec_wait1ms.s index 3da125d8..24ac3025 100644 --- a/c64/kernal/iec/iec_wait1ms.s +++ b/c64/kernal/iec/iec_wait1ms.s @@ -1,21 +1,21 @@ -;; -;; Wait 1 ms (1000 usec) -;; -;; On NTSC this means 1023 cycles (slightly less on PAL, but we have to be sure). -;; We can't count on badlines, as the screen might be disabled. -;; Delay here is implemeented using VIC-II raster register. Since one raster is -;; 63 cycles, we need at least 17 full rasters to be 100% sure we wait enough +// +// Wait 1 ms (1000 usec) +// +// On NTSC this means 1023 cycles (slightly less on PAL, but we have to be sure). +// We can't count on badlines, as the screen might be disabled. +// Delay here is implemeented using VIC-II raster register. Since one raster is +// 63 cycles, we need at least 17 full rasters to be 100% sure we wait enough iec_wait1ms: - ldx #18 ; we probably won't start with the beginning of raster + ldx #18 // we probably won't start with the beginning of raster lda VIC_RASTER -* +!: cmp VIC_RASTER - beq - + beq !- lda VIC_RASTER dex - bne - + bne !- rts diff --git a/c64/kernal/iec/iec_wait20us.s b/c64/kernal/iec/iec_wait20us.s index 819830cc..550de20c 100644 --- a/c64/kernal/iec/iec_wait20us.s +++ b/c64/kernal/iec/iec_wait20us.s @@ -1,22 +1,22 @@ iec_wait20us: - ;; Wait 20usec + // Wait 20usec - ;; PAL: - ;; - CPU frequency 0.985248 MHz, we need to waste at least 20 cycles - ;; NTSC: - ;; - CPU frequency 1.022727 MHz, we need to waste at least 21 cycles + // PAL: + // - CPU frequency 0.985248 MHz, we need to waste at least 20 cycles + // NTSC: + // - CPU frequency 1.022727 MHz, we need to waste at least 21 cycles - ;; Waste cycles by reading some unimportant memory location - ;; in order not to clutter VICE debug logs + // Waste cycles by reading some unimportant memory location + // in order not to clutter VICE debug logs - ora $03FF ; 4 cycles - ora $03FF ; 4 cycles - rts ; 6 cycles + ora $03FF // 4 cycles + ora $03FF // 4 cycles + rts // 6 cycles - ;; 6 cycles JSR to routine, - ;; 14 cycles routine with RTS - ;; 1 cycle to fetch next instruction - ;; --- - ;; 21 cycles + // 6 cycles JSR to routine, + // 14 cycles routine with RTS + // 1 cycle to fetch next instruction + // --- + // 21 cycles diff --git a/c64/kernal/iec/iec_wait60us.s b/c64/kernal/iec/iec_wait60us.s index 90501a5e..e5c7ad84 100644 --- a/c64/kernal/iec/iec_wait60us.s +++ b/c64/kernal/iec/iec_wait60us.s @@ -1,23 +1,23 @@ iec_wait60us: - ;; Wait 60usec + // Wait 60usec - ;; PAL: - ;; - CPU frequency 0.985248 MHz, we need to waste at least 60 cycles - ;; NTSC: - ;; - CPU frequency 1.022727 MHz, we need to waste at least 62 cycles + // PAL: + // - CPU frequency 0.985248 MHz, we need to waste at least 60 cycles + // NTSC: + // - CPU frequency 1.022727 MHz, we need to waste at least 62 cycles - ;; Waste cycles in a loop + // Waste cycles in a loop - ldy #$0A ; 2 cycles -* dey ; 2 cycles * 10 - bpl - ; 3 cycles * 9 + 2 cycles - rts ; 6 cycles + ldy #$0A // 2 cycles +!: dey // 2 cycles * 10 + bpl !- // 3 cycles * 9 + 2 cycles + rts // 6 cycles - ;; 6 cycles JSR to routine, - ;; 57 cycles routine with RTS - ;; 1 cycle to fetch next instruction - ;; --- - ;; 64 cycles + // 6 cycles JSR to routine, + // 57 cycles routine with RTS + // 1 cycle to fetch next instruction + // --- + // 64 cycles diff --git a/c64/kernal/iec/iec_wait_for_data_pull.s b/c64/kernal/iec/iec_wait_for_data_pull.s index 93bbabe9..9fcaa9fb 100644 --- a/c64/kernal/iec/iec_wait_for_data_pull.s +++ b/c64/kernal/iec/iec_wait_for_data_pull.s @@ -2,7 +2,7 @@ iec_wait_for_data_pull: lda CIA2_PRA - ;; Check the highest bit, which is DATA IN, - ;; (highest bit set = negative value) + // Check the highest bit, which is DATA IN, + // (highest bit set = negative value) bmi iec_wait_for_data_pull rts diff --git a/c64/kernal/iec/iec_wait_for_data_release.s b/c64/kernal/iec/iec_wait_for_data_release.s index dc89638a..93b4a518 100644 --- a/c64/kernal/iec/iec_wait_for_data_release.s +++ b/c64/kernal/iec/iec_wait_for_data_release.s @@ -2,7 +2,7 @@ iec_wait_for_data_release: lda CIA2_PRA - ;; Check the highest bit, which is DATA IN, - ;; (highest bit set = negative value) + // Check the highest bit, which is DATA IN, + // (highest bit set = negative value) bpl iec_wait_for_data_release rts diff --git a/c64/kernal/interrupts/ea31.default_irq_handler.s b/c64/kernal/interrupts/ea31.default_irq_handler.s index 944fe430..5ce46892 100644 --- a/c64/kernal/interrupts/ea31.default_irq_handler.s +++ b/c64/kernal/interrupts/ea31.default_irq_handler.s @@ -1,9 +1,10 @@ -default_irq_handler: +default_irq_handler: jsr blink_cursor jsr JSCNKEY - jsr JUDTIM ; update jiffy clock + jsr JUDTIM // update jiffy clock - ;; Acknowledge CIA interrupt and return + // Acknowledge CIA interrupt and return jmp clear_cia1_interrupt_flag_and_return_from_interrupt + diff --git a/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s b/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s index 9fd19423..ba5ebfa1 100644 --- a/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s +++ b/c64/kernal/interrupts/ea7e.ack_cia1_return_from_interrupt.s @@ -1,11 +1,11 @@ - ;; https://csdb.dk/forums/index.php?roomid=11&topicid=5776 - ;; Clear the CIA1 interrupt flag, and then fall through to - ;; the return from interrupt routine +// https://csdb.dk/forums/index.php?roomid=11&topicid=5776 +// Clear the CIA1 interrupt flag, and then fall through to +// the return from interrupt routine clear_cia1_interrupt_flag_and_return_from_interrupt: - ;; We have free choice of LDA, LDX or LDY to achieve this goal - ;; in 3 bytes and minimum cycles. Thus we randomly choose LDY. - LDY $DC0D + // We have free choice of LDA, LDX or LDY to achieve this goal + // in 3 bytes and minimum cycles. Thus we randomly choose LDY. + ldy CIA1_ICR - ;; FALL THROUGH to $EA81 + // FALL THROUGH to $EA81 diff --git a/c64/kernal/interrupts/ea81.return_from_interrupt.s b/c64/kernal/interrupts/ea81.return_from_interrupt.s index 077d2845..fa799bff 100644 --- a/c64/kernal/interrupts/ea81.return_from_interrupt.s +++ b/c64/kernal/interrupts/ea81.return_from_interrupt.s @@ -1,18 +1,20 @@ - ;; The IRQ is a commonly messed with thing on the C64, - ;; so we need to handle entry points that are commonly - ;; relied upon, including: - ;; $EA31 - Standard IRQ routine - ;; $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324 - ;; $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb - ;; Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb) +// The IRQ is a commonly messed with thing on the C64, +// so we need to handle entry points that are commonly +// relied upon, including: +// $EA31 - Standard IRQ routine +// $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324 +// $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb +// Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb) + return_from_interrupt: - ;; Restore registers and return - ;; Sequence according to Compute's Mapping the 64 p73 + + // Restore registers and return + // Sequence according to Compute's Mapping the 64 p73 pla tay pla tax pla rti - + diff --git a/c64/kernal/interrupts/fe47.default_nmi_handler.s b/c64/kernal/interrupts/fe47.default_nmi_handler.s index 1a1c915f..fdf3115c 100644 --- a/c64/kernal/interrupts/fe47.default_nmi_handler.s +++ b/c64/kernal/interrupts/fe47.default_nmi_handler.s @@ -1,34 +1,33 @@ default_nmi_handler: - ;; Implemented according to Compute's Mapping the Commodore 64, page 74 - ;; and to https://www.c64-wiki.com/wiki/Interrupt + // Implemented according to Compute's Mapping the Commodore 64, page 74 + // and to https://www.c64-wiki.com/wiki/Interrupt - ;; Save registers, sequence according to Compute's Mapping the Commodore 64, page 73 + // Save registers, sequence according to Compute's Mapping the Commodore 64, page 73 pha txa pha tya pha - ;; XXX: RS-232 support is not implemented + // XXX: RS-232 support is not implemented - ;; XXX confirm NMIs from CIA, or no other NMI will arrive! + // XXX confirm NMIs from CIA, or no other NMI will arrive! jsr cartridge_check - bcc + + bcc !+ jmp (ICART_WARM_START) -* +!: - ;; According to C64 Wiki, if STOP key is pressed, the routine assumes warm start request + // According to C64 Wiki, if STOP key is pressed, the routine assumes warm start request jsr JSTOP - bcs + - jmp return_from_interrupt ; no STOP pressed -* - ;; STOP + RESTORE - clean the address of the BRK instruction (it's not BRK) first + bcs !+ + jmp return_from_interrupt // no STOP pressed +!: + // STOP + RESTORE - clean the address of the BRK instruction (it's not BRK) first lda #$00 sta CMP0+0 sta CMP0+1 jmp (CBINV) - diff --git a/c64/kernal/interrupts/fe66.default_brk_handler.s b/c64/kernal/interrupts/fe66.default_brk_handler.s index 6b1f4c73..9e8adccb 100644 --- a/c64/kernal/interrupts/fe66.default_brk_handler.s +++ b/c64/kernal/interrupts/fe66.default_brk_handler.s @@ -1,13 +1,13 @@ default_brk_handler: - ;; Implemented according to Compute's Mapping the Commodore 64, pages 73-74 + // Implemented according to Compute's Mapping the Commodore 64, pages 73-74 - sei ; disable IRQs, to be sure they won't interfere + sei // disable IRQs, to be sure they won't interfere jsr JRESTOR jsr JIOINIT - jsr CINT_BRK + jsr cint_brk cli diff --git a/c64/kernal/interrupts/irq_handler.s b/c64/kernal/interrupts/irq_handler.s index 292f88e0..aec36752 100644 --- a/c64/kernal/interrupts/irq_handler.s +++ b/c64/kernal/interrupts/irq_handler.s @@ -1,38 +1,38 @@ irq_handler: - ;; The IRQ is a commonly messed with thing on the C64, - ;; so we need to handle entry points that are commonly - ;; relied upon, including: - ;; $EA31 - Standard IRQ routine - ;; $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324 - ;; $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb - ;; Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb) + // The IRQ is a commonly messed with thing on the C64, + // so we need to handle entry points that are commonly + // relied upon, including: + // $EA31 - Standard IRQ routine + // $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324 + // $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb + // Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb) - ;; Save registers, sequence according to Compute's Mapping the Commodore 64, page 73 + // Save registers, sequence according to Compute's Mapping the Commodore 64, page 73 pha txa pha tya pha - ;; Check if caused by BRK + // Check if caused by BRK tsx - lda $0104, x ; get the pre-interrupt processor state + lda $0104, x // get the pre-interrupt processor state and #$10 bne irq_handler_brk - ;; Not caused by BRK - call interrupt routine (only if initialised) + // Not caused by BRK - call interrupt routine (only if initialised) lda CINV ora CINV+1 - beq + + beq !+ jmp (CINV) -* - ;; Vector not initialized - call default interrupt routine +!: + // Vector not initialized - call default interrupt routine jmp default_irq_handler irq_handler_brk: - ;; Store BRK adddress, to be displayed + // Store BRK adddress, to be displayed sec lda $0105, x sbc #$02 @@ -41,6 +41,6 @@ irq_handler_brk: sbc #$00 sta CMP0+1 - ;; Interrupt caused by BRK + // Interrupt caused by BRK jmp (CBINV) diff --git a/c64/kernal/interrupts/nmi_handler.s b/c64/kernal/interrupts/nmi_handler.s index c5336f8b..77a7a948 100644 --- a/c64/kernal/interrupts/nmi_handler.s +++ b/c64/kernal/interrupts/nmi_handler.s @@ -1,17 +1,17 @@ nmi_handler: - sei ;; don't allow IRQ to interfere, see https://www.c64-wiki.com/wiki/Interrupt + sei // don't allow IRQ to interfere, see https://www.c64-wiki.com/wiki/Interrupt - ;; Call interrupt routine (only if initialised) + // Call interrupt routine (only if initialised) pha lda NMINV ora NMINV+1 - beq + + beq !+ pla jmp (NMINV) -* - ;; Vector not initialized - call default interrupt routine +!: + // Vector not initialized - call default interrupt routine pla jmp default_nmi_handler diff --git a/c64/kernal/jumptable/ff81.jcint.s b/c64/kernal/jumptable/ff81.jcint.s index e1504ab6..ea93a325 100644 --- a/c64/kernal/jumptable/ff81.jcint.s +++ b/c64/kernal/jumptable/ff81.jcint.s @@ -1,3 +1,4 @@ -; Initialise screen editor -; C64 Programmer's Reference Guide Page 272 - jmp cint +// Initialise screen editor +// C64 Programmer's Reference Guide Page 272 + + jmp CINT diff --git a/c64/kernal/jumptable/ff84.jioinit.s b/c64/kernal/jumptable/ff84.jioinit.s index af8a0abf..fda7c62c 100644 --- a/c64/kernal/jumptable/ff84.jioinit.s +++ b/c64/kernal/jumptable/ff84.jioinit.s @@ -1,3 +1,4 @@ -; Initialise input/output -; C64 Programmer's Reference Guide Page 272 - jmp ioinit +// Initialise input/output +// C64 Programmer's Reference Guide Page 272 + + jmp IOINIT diff --git a/c64/kernal/jumptable/ff87.jramtas.s b/c64/kernal/jumptable/ff87.jramtas.s index 1c4ecc4e..616021c5 100644 --- a/c64/kernal/jumptable/ff87.jramtas.s +++ b/c64/kernal/jumptable/ff87.jramtas.s @@ -1,3 +1,4 @@ -; Initialise RAM, allocate tape buffer, set screen to $0400 -; C64 Programmer's Reference Guide Page 273 - jmp ramtas +// Initialise RAM, allocate tape buffer, set screen to $0400 +// C64 Programmer's Reference Guide Page 273 + + jmp RAMTAS diff --git a/c64/kernal/jumptable/ff8a.jrestor.s b/c64/kernal/jumptable/ff8a.jrestor.s index dd56e8b4..0fa0057e 100644 --- a/c64/kernal/jumptable/ff8a.jrestor.s +++ b/c64/kernal/jumptable/ff8a.jrestor.s @@ -1,3 +1,4 @@ -; Restore default IO vectors -; C64 Programmer's Reference Guide Page 273 - jmp restor +// Restore default IO vectors +// C64 Programmer's Reference Guide Page 273 + + jmp RESTOR diff --git a/c64/kernal/jumptable/ff8d.jvector.s b/c64/kernal/jumptable/ff8d.jvector.s index 6384b9ac..cd0b9990 100644 --- a/c64/kernal/jumptable/ff8d.jvector.s +++ b/c64/kernal/jumptable/ff8d.jvector.s @@ -1,3 +1,4 @@ -; Read/set vectored I/O -; C64 Programmer's Reference Guide Page 273 - jmp vector +// Read/set vectored I/O +// C64 Programmer's Reference Guide Page 273 + + jmp VECTOR diff --git a/c64/kernal/jumptable/ff90.jsetmsg.s b/c64/kernal/jumptable/ff90.jsetmsg.s index 0e127328..7f54b3ac 100644 --- a/c64/kernal/jumptable/ff90.jsetmsg.s +++ b/c64/kernal/jumptable/ff90.jsetmsg.s @@ -1,3 +1,4 @@ -; Control KERNAL messages -; C64 Programmer's Reference Guide Page 273 - jmp setmsg +// Control KERNAL messages +// C64 Programmer's Reference Guide Page 273 + + jmp SETMSG diff --git a/c64/kernal/jumptable/ff93.jsecond.s b/c64/kernal/jumptable/ff93.jsecond.s index 69dcabe9..6ae355f0 100644 --- a/c64/kernal/jumptable/ff93.jsecond.s +++ b/c64/kernal/jumptable/ff93.jsecond.s @@ -1,3 +1,4 @@ -; SEnd secondary address after LISTEN -; C64 Programmer's Reference Guide Page 273 - jmp second +// Send secondary address after LISTEN +// C64 Programmer's Reference Guide Page 273 + + jmp SECOND diff --git a/c64/kernal/jumptable/ff96.jtksa.s b/c64/kernal/jumptable/ff96.jtksa.s index 4e935de7..5f710af0 100644 --- a/c64/kernal/jumptable/ff96.jtksa.s +++ b/c64/kernal/jumptable/ff96.jtksa.s @@ -1,3 +1,4 @@ -; Send secondary address after talk -; C64 Programmer's Reference Guide Page 273 - jmp tksa +// Send secondary address after talk +// C64 Programmer's Reference Guide Page 273 + + jmp TKSA diff --git a/c64/kernal/jumptable/ff99.jmemtop.s b/c64/kernal/jumptable/ff99.jmemtop.s index 4b86e2ad..b6653e94 100644 --- a/c64/kernal/jumptable/ff99.jmemtop.s +++ b/c64/kernal/jumptable/ff99.jmemtop.s @@ -1,3 +1,4 @@ -; read/set the top of memory -; C64 Programmer's Reference Guide Page 272 - jmp memtop +// read/set the top of memory +// C64 Programmer's Reference Guide Page 272 + + jmp MEMTOP diff --git a/c64/kernal/jumptable/ff9c.jmembot.s b/c64/kernal/jumptable/ff9c.jmembot.s index a21e0575..8745f99b 100644 --- a/c64/kernal/jumptable/ff9c.jmembot.s +++ b/c64/kernal/jumptable/ff9c.jmembot.s @@ -1,3 +1,4 @@ -; read/set the bottom of memory -; C64 Programmer's Reference Guide Page 272 - jmp membot +// read/set the bottom of memory +// C64 Programmer's Reference Guide Page 272 + + jmp MEMBOT diff --git a/c64/kernal/jumptable/ff9f.jscnkey.s b/c64/kernal/jumptable/ff9f.jscnkey.s index 2f445ce4..5d71d27d 100644 --- a/c64/kernal/jumptable/ff9f.jscnkey.s +++ b/c64/kernal/jumptable/ff9f.jscnkey.s @@ -1,3 +1,4 @@ -; Scan keyboard -; C64 Programmer's Reference Guide Page 273 +// Scan keyboard +// C64 Programmer's Reference Guide Page 273 + jmp SCNKEY diff --git a/c64/kernal/jumptable/ffa2.jsettmo.s b/c64/kernal/jumptable/ffa2.jsettmo.s index be75bdf3..3d82b696 100644 --- a/c64/kernal/jumptable/ffa2.jsettmo.s +++ b/c64/kernal/jumptable/ffa2.jsettmo.s @@ -1,3 +1,4 @@ -; Set timeout on serial bus -; C64 Programmer's Reference Guide Page 273 - jmp settmo +// Set timeout on serial bus +// C64 Programmer's Reference Guide Page 273 + + jmp SETTMO diff --git a/c64/kernal/jumptable/ffa5.jacptr.s b/c64/kernal/jumptable/ffa5.jacptr.s index 521185ac..6446229f 100644 --- a/c64/kernal/jumptable/ffa5.jacptr.s +++ b/c64/kernal/jumptable/ffa5.jacptr.s @@ -1,3 +1,4 @@ -; Input byte from serial port -; C64 Programmer's Reference Guide Page 272 - jmp acptr +// Input byte from serial port +// C64 Programmer's Reference Guide Page 272 + + jmp ACPTR diff --git a/c64/kernal/jumptable/ffa8.jciout.s b/c64/kernal/jumptable/ffa8.jciout.s index 1bccfff8..2838110a 100644 --- a/c64/kernal/jumptable/ffa8.jciout.s +++ b/c64/kernal/jumptable/ffa8.jciout.s @@ -1,3 +1,4 @@ -; Output byte to serial port -; C64 Programmer's Reference Guide Page 272 - jmp ciout +// Output byte to serial port +// C64 Programmer's Reference Guide Page 272 + + jmp CIOUT diff --git a/c64/kernal/jumptable/ffab.juntlk.s b/c64/kernal/jumptable/ffab.juntlk.s index f73f5ec8..dc6ebbe0 100644 --- a/c64/kernal/jumptable/ffab.juntlk.s +++ b/c64/kernal/jumptable/ffab.juntlk.s @@ -1,3 +1,4 @@ -; Command serial bus to UNTALK -; C64 Programmer's Reference Guide Page 273 - jmp untlk +// Command serial bus to UNTALK +// C64 Programmer's Reference Guide Page 273 + + jmp UNTLK diff --git a/c64/kernal/jumptable/ffae.junlsn.s b/c64/kernal/jumptable/ffae.junlsn.s index 8f1209d4..55cab36f 100644 --- a/c64/kernal/jumptable/ffae.junlsn.s +++ b/c64/kernal/jumptable/ffae.junlsn.s @@ -1,3 +1,4 @@ -; Command serial bus to UNLISTEN -; C64 Programmer's Reference Guide Page 273 - jmp unlsn +// Command serial bus to UNLISTEN +// C64 Programmer's Reference Guide Page 273 + + jmp UNLSN diff --git a/c64/kernal/jumptable/ffb1.jlisten.s b/c64/kernal/jumptable/ffb1.jlisten.s index a4040c5a..e93c9be8 100644 --- a/c64/kernal/jumptable/ffb1.jlisten.s +++ b/c64/kernal/jumptable/ffb1.jlisten.s @@ -1,3 +1,4 @@ -; Command devices on the serial bus to listen -; C64 Programmer's Reference Guide Page 272 - jmp listen +// Command devices on the serial bus to listen +// C64 Programmer's Reference Guide Page 272 + + jmp LISTEN diff --git a/c64/kernal/jumptable/ffb4.jtalk.s b/c64/kernal/jumptable/ffb4.jtalk.s index 4a4cf685..f94fffd3 100644 --- a/c64/kernal/jumptable/ffb4.jtalk.s +++ b/c64/kernal/jumptable/ffb4.jtalk.s @@ -1,3 +1,4 @@ -; Command serial bus device to talk -; C64 Programmer's Reference Guide Page 273 - jmp talk +// Command serial bus device to talk +// C64 Programmer's Reference Guide Page 273 + + jmp TALK diff --git a/c64/kernal/jumptable/ffb7.jreadst.s b/c64/kernal/jumptable/ffb7.jreadst.s index fb082d30..46fcc2fd 100644 --- a/c64/kernal/jumptable/ffb7.jreadst.s +++ b/c64/kernal/jumptable/ffb7.jreadst.s @@ -1,3 +1,4 @@ -; Read I/O statusjmp -; C64 Programmer's Reference Guide Page 273 - jmp readst +// Read I/O statusjmp +// C64 Programmer's Reference Guide Page 273 + + jmp READST diff --git a/c64/kernal/jumptable/ffba.jsetfls.s b/c64/kernal/jumptable/ffba.jsetfls.s index 6ad1fe44..ec77c14a 100644 --- a/c64/kernal/jumptable/ffba.jsetfls.s +++ b/c64/kernal/jumptable/ffba.jsetfls.s @@ -1,3 +1,4 @@ -; Set logical, first and second addresses -; C64 Programmer's Reference Guide Page 273 - jmp setfls +// Set logical, first and second addresses +// C64 Programmer's Reference Guide Page 273 + + jmp SETFLS diff --git a/c64/kernal/jumptable/ffbd.jsetnam.s b/c64/kernal/jumptable/ffbd.jsetnam.s index b215a106..e0e3871e 100644 --- a/c64/kernal/jumptable/ffbd.jsetnam.s +++ b/c64/kernal/jumptable/ffbd.jsetnam.s @@ -1,3 +1,4 @@ -; Set file name -; C64 Programmer's Reference Guide Page 273 - jmp setnam +// Set file name +// C64 Programmer's Reference Guide Page 273 + + jmp SETNAM diff --git a/c64/kernal/jumptable/ffc0.jopen.s b/c64/kernal/jumptable/ffc0.jopen.s index 7aafbb7e..82a5aa1b 100644 --- a/c64/kernal/jumptable/ffc0.jopen.s +++ b/c64/kernal/jumptable/ffc0.jopen.s @@ -1,4 +1,5 @@ -; open a logical file -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// open a logical file +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (IOPEN) diff --git a/c64/kernal/jumptable/ffc3.jclose.s b/c64/kernal/jumptable/ffc3.jclose.s index b59159d3..badb18c8 100644 --- a/c64/kernal/jumptable/ffc3.jclose.s +++ b/c64/kernal/jumptable/ffc3.jclose.s @@ -1,4 +1,5 @@ -; close a specified logical file -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// close a specified logical file +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (ICLOSE) diff --git a/c64/kernal/jumptable/ffc6.jchkin.s b/c64/kernal/jumptable/ffc6.jchkin.s index da8948c7..b06874ef 100644 --- a/c64/kernal/jumptable/ffc6.jchkin.s +++ b/c64/kernal/jumptable/ffc6.jchkin.s @@ -1,4 +1,5 @@ -; Open channel for input -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// Open channel for input +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (ICHKIN) diff --git a/c64/kernal/jumptable/ffc9.jckout.s b/c64/kernal/jumptable/ffc9.jckout.s index f394d46d..64ff0481 100644 --- a/c64/kernal/jumptable/ffc9.jckout.s +++ b/c64/kernal/jumptable/ffc9.jckout.s @@ -1,4 +1,5 @@ -; Open channel for output -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// Open channel for output +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (ICKOUT) diff --git a/c64/kernal/jumptable/ffcc.jclrchn.s b/c64/kernal/jumptable/ffcc.jclrchn.s index 9fb7697c..a207f2e4 100644 --- a/c64/kernal/jumptable/ffcc.jclrchn.s +++ b/c64/kernal/jumptable/ffcc.jclrchn.s @@ -1,4 +1,5 @@ -; close input and output channels -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// close input and output channels +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (ICLRCH) diff --git a/c64/kernal/jumptable/ffcf.jchrin.s b/c64/kernal/jumptable/ffcf.jchrin.s index 465ac6b8..de1ae44e 100644 --- a/c64/kernal/jumptable/ffcf.jchrin.s +++ b/c64/kernal/jumptable/ffcf.jchrin.s @@ -1,4 +1,5 @@ -; Input character from channel -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// Input character from channel +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (IBASIN) diff --git a/c64/kernal/jumptable/ffd2.jchrout.s b/c64/kernal/jumptable/ffd2.jchrout.s index 318b26cf..c3f31a0e 100644 --- a/c64/kernal/jumptable/ffd2.jchrout.s +++ b/c64/kernal/jumptable/ffd2.jchrout.s @@ -1,4 +1,5 @@ -; Output character to channel -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// Output character to channel +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (IBSOUT) diff --git a/c64/kernal/jumptable/ffd5.jload.s b/c64/kernal/jumptable/ffd5.jload.s index 4e51c899..b632434d 100644 --- a/c64/kernal/jumptable/ffd5.jload.s +++ b/c64/kernal/jumptable/ffd5.jload.s @@ -1,3 +1,4 @@ -; load RAM from a device -; C64 Programmer's Reference Guide Page 272 - jmp load +// load RAM from a device +// C64 Programmer's Reference Guide Page 272 + + jmp LOAD diff --git a/c64/kernal/jumptable/ffd8.jsave.s b/c64/kernal/jumptable/ffd8.jsave.s index 4e95e566..1ac529e4 100644 --- a/c64/kernal/jumptable/ffd8.jsave.s +++ b/c64/kernal/jumptable/ffd8.jsave.s @@ -1,3 +1,4 @@ -; SAVE RAM to device -; C64 Programmer's Reference Guide Page 273 - jmp save +// SAVE RAM to device +// C64 Programmer's Reference Guide Page 273 + + jmp SAVE diff --git a/c64/kernal/jumptable/ffdb.jsettim.s b/c64/kernal/jumptable/ffdb.jsettim.s index d6bed384..61625a29 100644 --- a/c64/kernal/jumptable/ffdb.jsettim.s +++ b/c64/kernal/jumptable/ffdb.jsettim.s @@ -1,3 +1,4 @@ -; Set realtime clock -; C64 Programmer's Reference Guide Page 273 - jmp settim +// Set realtime clock +// C64 Programmer's Reference Guide Page 273 + + jmp SETTIM diff --git a/c64/kernal/jumptable/ffde.jrdtim.s b/c64/kernal/jumptable/ffde.jrdtim.s index 295ea0d9..5a190b14 100644 --- a/c64/kernal/jumptable/ffde.jrdtim.s +++ b/c64/kernal/jumptable/ffde.jrdtim.s @@ -1,3 +1,4 @@ -; Read real time clock -; C64 Programmer's Reference Guide Page 273 - jmp rdtim +// Read real time clock +// C64 Programmer's Reference Guide Page 273 + + jmp RDTIM diff --git a/c64/kernal/jumptable/ffe1.jstop.s b/c64/kernal/jumptable/ffe1.jstop.s index e5b6c4ec..0938b7d1 100644 --- a/c64/kernal/jumptable/ffe1.jstop.s +++ b/c64/kernal/jumptable/ffe1.jstop.s @@ -1,4 +1,5 @@ -; Scan stop key -; C64 Programmer's Reference Guide Page 273 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// Scan stop key +// C64 Programmer's Reference Guide Page 273 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (ISTOP) diff --git a/c64/kernal/jumptable/ffe4.jgetin.s b/c64/kernal/jumptable/ffe4.jgetin.s index c9f67cf4..feafd28c 100644 --- a/c64/kernal/jumptable/ffe4.jgetin.s +++ b/c64/kernal/jumptable/ffe4.jgetin.s @@ -1,4 +1,5 @@ -; Get character from keyboard queue (keyboard buffer) -; C64 Programmer's Reference Guide Page 272 -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// Get character from keyboard queue (keyboard buffer) +// C64 Programmer's Reference Guide Page 272 +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (IGETIN) diff --git a/c64/kernal/jumptable/ffe7.jclall.s b/c64/kernal/jumptable/ffe7.jclall.s index f5050a8a..287f85ac 100644 --- a/c64/kernal/jumptable/ffe7.jclall.s +++ b/c64/kernal/jumptable/ffe7.jclall.s @@ -1,4 +1,5 @@ -; $FFE7 - Close all files vector -; (http://codebase64.org/doku.php?id=base:kernalreference) -; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect +// $FFE7 - Close all files vector +// (http://codebase64.org/doku.php?id=base:kernalreference) +// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect + jmp (ICLALL) diff --git a/c64/kernal/jumptable/ffea.judtim.s b/c64/kernal/jumptable/ffea.judtim.s index 5cb58e73..bccd0603 100644 --- a/c64/kernal/jumptable/ffea.judtim.s +++ b/c64/kernal/jumptable/ffea.judtim.s @@ -1,4 +1,4 @@ -; $FFEA - Update jiffy clock vector -; (http://codebase64.org/doku.php?id=base:kernalreference) +// $FFEA - Update jiffy clock vector +// (http://codebase64.org/doku.php?id=base:kernalreference) jmp UDTIM diff --git a/c64/kernal/jumptable/ffed.jscreen.s b/c64/kernal/jumptable/ffed.jscreen.s index 55d44e37..8f58f3f2 100644 --- a/c64/kernal/jumptable/ffed.jscreen.s +++ b/c64/kernal/jumptable/ffed.jscreen.s @@ -1,4 +1,4 @@ -; $FFED - Return screen size (X=columns, Y=rows) -; (http://codebase64.org/doku.php?id=base:kernalreference) +// $FFED - Return screen size (X=columns, Y=rows) +// (http://codebase64.org/doku.php?id=base:kernalreference) - jmp screen + jmp SCREEN diff --git a/c64/kernal/jumptable/fff0.jplot.s b/c64/kernal/jumptable/fff0.jplot.s index 38f974ae..2a9f782c 100644 --- a/c64/kernal/jumptable/fff0.jplot.s +++ b/c64/kernal/jumptable/fff0.jplot.s @@ -1,6 +1,6 @@ -; $FFF0 - Get/Set cursor location vector -; (http://codebase64.org/doku.php?id=base:kernalreference) -; To set: C=0, to get, C=1 -; X=row, Y=column +// $FFF0 - Get/Set cursor location vector +// (http://codebase64.org/doku.php?id=base:kernalreference) +// To set: C=0, to get, C=1 +// X=row, Y=column - jmp plot + jmp PLOT diff --git a/c64/kernal/jumptable/fff3.jiobase.s b/c64/kernal/jumptable/fff3.jiobase.s index 1c459c5d..3fbd234c 100644 --- a/c64/kernal/jumptable/fff3.jiobase.s +++ b/c64/kernal/jumptable/fff3.jiobase.s @@ -1,16 +1,16 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 284 -;; - [CM64] Compute's Mapping the Commodore 64 - page 214 -;; - http://codebase64.org/doku.php?id=base:kernalreference (original source) -;; -;; CPU registers that has to be preserved (see [RG64]): .A -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 284 +// - [CM64] Compute's Mapping the Commodore 64 - page 214 +// - http://codebase64.org/doku.php?id=base:kernalreference (original source) +// +// CPU registers that has to be preserved (see [RG64]): .A +// -;; As there is nothing between here and $FFFA, we can just hard code this in place. +// As there is nothing between here and $FFFA, we can just hard code this in place. iobase: ldy #$DC diff --git a/c64/kernal/keyboard_matrix.s b/c64/kernal/keyboard_matrix.s index da07107c..e4c58270 100644 --- a/c64/kernal/keyboard_matrix.s +++ b/c64/kernal/keyboard_matrix.s @@ -1,12 +1,11 @@ - ;; Key board matrixes: - ;; unshifted, shifted, control and C= modified - ;; 64 bytes for each +// Key board matrixes: unshifted, shifted, control and C= modified +// 64 bytes for each keyboard_matrixes: - ;; Unshifted matrix built by refering to - ;; Compute's Mapping the 64 p38-39 - ;; and C64 PRG pages 379-381 + // Unshifted matrix built by refering to + // Compute's Mapping the 64 p38-39 + // and C64 PRG pages 379-381 .byte $14,$0D,$1D,$88,$85,$86,$87,17 .byte $33,87,$41,$34,$5A,83,$45,$00 .byte $35,$52,$44,$36,$43,$46,$54,88 @@ -16,11 +15,11 @@ keyboard_matrixes: .byte $5C,$2A,59,$13,$00,$3D,$5E,$2F .byte $31,$5F,$00,$32,$20,$00,$51,$03 - ;; Shifted keyboard - ;; Values computed by running a program like: - ;; 10 GETA$:IFA$=""GOTO10 - ;; 20 ?ASC(A$):GOTO10 - ;; and converting the values + // Shifted keyboard + // Values computed by running a program like: + // 10 GETA$:IFA$=""GOTO10 + // 20 ?ASC(A$):GOTO10 + // and converting the values .byte $94,$8D,$9D,$8C,$89,$8A,$8B,$91 .byte $23,$77,$61,$24,$7A,$73,$65,$00 .byte $25,$72,$64,$26,$63,$66,$74,$78 @@ -30,7 +29,7 @@ keyboard_matrixes: .byte $A9,$C0,$5D,$93,$00,$3D,$DE,$3F .byte $21,$5F,$00,$22,$A0,$00,$71,$83 - ;; Vendor key modified keyboard + // Vendor key modified keyboard .byte $94,$8D,$9D,$8C,$89,$8A,$8B,$91 .byte $96,$B3,$B0,$97,$AD,$AE,$B1,$00 .byte $98,$B2,$AC,$99,$BC,$BB,$A3,$BD @@ -40,7 +39,7 @@ keyboard_matrixes: .byte $A8,$DF,$5D,$93,$00,$3D,$DE,$3F .byte $81,$5F,$00,$95,$a0,$00,$AB,$83 - ;; Control modified keyboard + // Control modified keyboard .byte $00,$00,$00,$00,$00,$00,$00,$00 .byte $1C,$17,$01,$9F,$1A,$13,$05,$00 .byte $9C,$12,$04,$1E,$03,$06,$14,$18 @@ -52,22 +51,22 @@ keyboard_matrixes: keyboard_matrix_lookup: - ;; Work out if normal, shifted, control or Vendor - ;; modified keyboard. - ;; Table contains the offsets into keyboard_matrixes - ;; that should be used for different values of - ;; the bottom 3 bits of key_bucky_state - ;; Interaction is simple to work out when playing - ;; with a C64: - ;; CONTROL trumps SHIFT or Vendor - ;; Vendor + SHIFT = DOES NOTHING - ;; All 3 does CONTROL - .byte $00 ; Normal - .byte $40 ; Shifted - .byte $80 ; Control - .byte $80 ; Control + SHIFT - .byte $C0 ; Vendor - .byte $C0 ; Vendor + SHIFT - .byte $80 ; Vendor+ CTRL - .byte $80 ; Vendor + CTRL + SHIFT + // Work out if normal, shifted, control or Vendor + // modified keyboard. + // Table contains the offsets into keyboard_matrixes + // that should be used for different values of + // the bottom 3 bits of key_bucky_state + // Interaction is simple to work out when playing + // with a C64: + // CONTROL trumps SHIFT or Vendor + // Vendor + SHIFT = DOES NOTHING + // All 3 does CONTROL + .byte $00 // Normal + .byte $40 // Shifted + .byte $80 // Control + .byte $80 // Control + SHIFT + .byte $C0 // Vendor + .byte $C0 // Vendor + SHIFT + .byte $80 // Vendor+ CTRL + .byte $80 // Vendor + CTRL + SHIFT diff --git a/c64/kernal/listen.s b/c64/kernal/listen.s index dd240070..edb72e87 100644 --- a/c64/kernal/listen.s +++ b/c64/kernal/listen.s @@ -1,27 +1,27 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 285 -;; - [CM64] Compute's Mapping the Commodore 64 - page 223 -;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc -;; - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 285 +// - [CM64] Compute's Mapping the Commodore 64 - page 223 +// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc +// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -listen: +LISTEN: - ;; According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer + // According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer jsr iec_tx_flush - ;; Check whether device number is correct + // Check whether device number is correct jsr iec_check_devnum - bcc + + bcc !+ jmp kernalerror_DEVICE_NOT_FOUND -* - ;; Encode and execute the command +!: + // Encode and execute the command ora #$20 jmp common_talk_listen diff --git a/c64/kernal/lvs_helpers.s b/c64/kernal/lvs_helpers.s index d52c1bcf..2998b7e1 100644 --- a/c64/kernal/lvs_helpers.s +++ b/c64/kernal/lvs_helpers.s @@ -1,160 +1,168 @@ - -;; -;; Helper functions for various LOAD/VERIVY/SAVE routine variants (IEC / U64 / etc.) -;; - -lvs_send_file_name: - ldy #0 -lvs_send_file_name_loop: - cpy FNLEN - beq lvs_send_file_name_done - ldx #$033C sta cassette_buffer_ptr+1 - ; set screen address to $0400 - ; https://www.c64-wiki.com/wiki/Screen_RAM - ; Since we are setting $D018, we also make sure we are using the - ; ROM character set (C64 Programmer's Reference Guide p322) + // set screen address to $0400 + // https://www.c64-wiki.com/wiki/Screen_RAM + // Since we are setting $D018, we also make sure we are using the + // ROM character set (C64 Programmer's Reference Guide p322) lda #$14 sta VIC_YMCSB - ; Make sure we have the correct VIC-II memory bank for the screen to really be at $0400 - ; and not $4400, $8400 or $C400 - ; https://www.c64-wiki.com/wiki/VIC_bank#Selecting_VIC_banks + // Make sure we have the correct VIC-II memory bank for the screen to really be at $0400 + // and not $4400, $8400 or $C400 + // https://www.c64-wiki.com/wiki/VIC_bank#Selecting_VIC_banks lda CIA2_DDRA ora #$03 sta CIA2_DDRA @@ -54,22 +54,22 @@ ramtas_l2: ora #$03 sta CIA2_PRA - ;; Set screen address pointer ("Compute's Mapping the 64" p238) - ;; This is obvious boiler plate containing no creative input, but to avoid - ;; unnecessarily similarity to the C64 KERNAL, we use X instead of A to do this, - ;; and several following + // Set screen address pointer ("Compute's Mapping the 64" p238) + // This is obvious boiler plate containing no creative input, but to avoid + // unnecessarily similarity to the C64 KERNAL, we use X instead of A to do this, + // and several following ldx #>$0400 stx HIBASE - ;; Work out RAM size and put in MEMSTR and MEMSIZ - ;; "Compute's Mapping the 64", p54 - ;; http://unusedino.de/ec64/technical/project64/mapping_c64.html + // Work out RAM size and put in MEMSTR and MEMSIZ + // "Compute's Mapping the 64", p54 + // http://unusedino.de/ec64/technical/project64/mapping_c64.html ldx #>$0800 stx MEMSTR+1 ldx #$00 stx MEMSTR+0 stx MEMSIZ+0 - ;; Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF + // Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF lda $8000 eor #$FF tax @@ -82,10 +82,10 @@ ramtas_l2: stx MEMSIZ+1 jmp ramtas_RAM_sized ramtas_32K_RAM: - sta $8000 ; in case RAM is hiding beneath a ROM + sta $8000 // in case RAM is hiding beneath a ROM ldx #$80 stx MEMSIZ+1 - ;; Fall through + // Fall through ramtas_RAM_sized: rts diff --git a/c64/kernal/rdtim.s b/c64/kernal/rdtim.s index 41ad0b94..37009289 100644 --- a/c64/kernal/rdtim.s +++ b/c64/kernal/rdtim.s @@ -1,27 +1,27 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 291 -;; - [CM64] Compute's Mapping the Commodore 64 - page 232 -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 291 +// - [CM64] Compute's Mapping the Commodore 64 - page 232 +// +// CPU registers that has to be preserved (see [RG64]): none +// -rdtim: +RDTIM: - ;; Disable interrupts for the duration of the routine, to prevent - ;; jiffy clock update while reeading it's values + // Disable interrupts for the duration of the routine, to prevent + // jiffy clock update while reeading it's values sei - ;; Store the jiffy clock state - ldy TIME + 0 - ldx TIME + 1 - lda TIME + 2 + // Store the jiffy clock state + ldy TIME+0 + ldx TIME+1 + lda TIME+2 - ;; Enable interrupts. More elegant solution would be pha + sei + ... + pla, - ;; but (checked by running a test program) original ROM routine always - ;; leaves IRQs enabled. + // Enable interrupts. More elegant solution would be pha + sei + ... + pla, + // but (checked by running a test program) original ROM routine always + // leaves IRQs enabled. cli rts diff --git a/c64/kernal/readst.s b/c64/kernal/readst.s index b3fbaa53..5be3e2c9 100644 --- a/c64/kernal/readst.s +++ b/c64/kernal/readst.s @@ -1,30 +1,30 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 292 -;; - [CM64] Compute's Mapping the Commodore 64 - page 239 -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 292 +// - [CM64] Compute's Mapping the Commodore 64 - page 239 +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -readst: +READST: - ;; Check the current device number + // Check the current device number lda current_device_number cmp #$02 - bne + + bne !+ - ;; This is RS-232 device - according to 'Compute's Mapping the Commodore 64' page 239 - ;; it reads status from RSSTAT + // This is RS-232 device - according to 'Compute's Mapping the Commodore 64' page 239 + // it reads status from RSSTAT lda RSSTAT rts -* - ;; According to 'Compute's Mapping the Commodore 64' page 239, it usually retrieves - ;; status from IOSTATUS +!: + // According to 'Compute's Mapping the Commodore 64' page 239, it usually retrieves + // status from IOSTATUS - ;; XXX is it always the case if device is not RS-232 ? + // XXX is it always the case if device is not RS-232 ? lda IOSTATUS rts diff --git a/c64/kernal/reset_entry.s b/c64/kernal/reset_entry.s index 7fb0b6a7..9eb9eca7 100644 --- a/c64/kernal/reset_entry.s +++ b/c64/kernal/reset_entry.s @@ -1,42 +1,42 @@ -; Resources describing the C64 reset sequence: -; https://www.c64-wiki.com/wiki/Reset_(Process) +// Resources describing the C64 reset sequence: +// https://www.c64-wiki.com/wiki/Reset_(Process) reset_entry: - ; The GPL program at https://github.com/Klaus2m5/6502_65C02_functional_tests/blob/master/6502_functional_test.a65 - ; uses the following initial reset sequence - ; affirmed by c64 PRG p269 + // The GPL program at https://github.com/Klaus2m5/6502_65C02_functional_tests/blob/master/6502_functional_test.a65 + // uses the following initial reset sequence + // affirmed by c64 PRG p269 cld ldx #$ff txs sei - ; The following routine is based on reading the public KERNAL jumptable routine - ; list, and making unimaginative assumptions about what should be done on reset. - ; Also, https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image was used - ; as it shows example startup sequence, to be followe by cartridge creators + // The following routine is based on reading the public KERNAL jumptable routine + // list, and making unimaginative assumptions about what should be done on reset. + // Also, https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image was used + // as it shows example startup sequence, to be followe by cartridge creators - ; C64 PRG p269 + // C64 PRG p269 jsr cartridge_check - bcc + + bcc !+ jmp (ICART_COLD_START) -* - ; Initialising IO is obviously required. Also indicated by c64 prg p269. +!: + // Initialising IO is obviously required. Also indicated by c64 prg p269. jsr JIOINIT - ; Setting up the screen and testing ram is obviously required - ; also affirmed by p269 of c64 prg - jsr JRAMTAS ; called RANTAM on Codebase64 wiki + // Setting up the screen and testing ram is obviously required + // also affirmed by p269 of c64 prg + jsr JRAMTAS // called RANTAM on Codebase64 wiki - ; Resetting IO vectors is obviously required, if we want interrupts to run - ; also affirmed by c64 prg p269 + // Resetting IO vectors is obviously required, if we want interrupts to run + // also affirmed by c64 prg p269 jsr JRESTOR - ;; "Compute's Mapping the 64" p236 + // "Compute's Mapping the 64" p236 jsr JCINT - ; What do we do when finished? A C64 jumps into the BASIC ROM - cli ; Allow interrupts to happen + // What do we do when finished? A C64 jumps into the BASIC ROM + cli // Allow interrupts to happen - ; c64 prg p269 + // c64 prg p269 jmp (IBASIC_COLD_START) diff --git a/c64/kernal/scnkey.s b/c64/kernal/scnkey.s index 87e52bfc..6bf96d90 100644 --- a/c64/kernal/scnkey.s +++ b/c64/kernal/scnkey.s @@ -1,115 +1,114 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 295 -;; - [CM64] Compute's Mapping the Commodore 64 - page 220 -;; -;; CPU registers that has to be preserved (see [RG64]): none -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 295 +// - [CM64] Compute's Mapping the Commodore 64 - page 220 +// +// CPU registers that has to be preserved (see [RG64]): none +// -;; Scan the keyboard.. -;; Here we don't use the horrible buggy original routine, -;; not just because of copyright. Instead, we use the -;; nice one with joystick interference removal and -;; key roll-over support from -;; http://codebase64.org/doku.php?id=base:scanning_the_keyboard_the_correct_and_non_kernal_way +// Scan the keyboard.. +// Here we don't use the horrible buggy original routine, +// not just because of copyright. Instead, we use the +// nice one with joystick interference removal and +// key roll-over support from +// http://codebase64.org/doku.php?id=base:scanning_the_keyboard_the_correct_and_non_kernal_way -;; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -;; Keyboard IO Routine -;; ~~~~~~~~~~~~~~~~~~~ -;; By: TWW/CTR +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Keyboard IO Routine +// ~~~~~~~~~~~~~~~~~~~ +// By: TWW/CTR -;; Information -;; ~~~~~~~~~~~ -;; The routine uses "2 Key rollower" or up to 3 if the key-combination doesen't induce shadowing. -;; If 2 or 3 keys are pressed simultaneously (within 1 scan) a "No Activity" state has to occur before new valid keys are returned. -;; RESTORE is not detectable and must be handled by NMI IRQ. -;; SHIFT LOCK is not detected due to unreliability. +// Information +// ~~~~~~~~~~~ +// The routine uses "2 Key rollower" or up to 3 if the key-combination doesen't induce shadowing. +// If 2 or 3 keys are pressed simultaneously (within 1 scan) a "No Activity" state has to occur before new valid keys are returned. +// RESTORE is not detectable and must be handled by NMI IRQ. +// SHIFT LOCK is not detected due to unreliability. -;; History: -;; ~~~~~~~~ -;; V3.0 - Hacked to pieces by PGS to work as KERNAL keyboard scan routine -;; V2.5 - New test tool. -;; Added return of error codes. -;; Fixed a bug causing Buffer Overflow. -;; Fixed a bug in Non Alphanumerical Flags from 2.0. -;; V2.1 - Shortened the source by adding .for loops & Updated the header and some comments. -;; Added "simultaneous keypress" check. -;; V2.0 - Added return of non-Alphanumeric keys into X & Y-Registers. -;; Small optimizations here and there. -;; V1.1 - Unrolled code to make it faster and optimized other parts of it. -;; Removed SHIFT LOCK scanning. -;; V1.0 - First Working Version along with test tool. +// History: +// ~~~~~~~~ +// V3.0 - Hacked to pieces by PGS to work as KERNAL keyboard scan routine +// V2.5 - New test tool. +// Added return of error codes. +// Fixed a bug causing Buffer Overflow. +// Fixed a bug in Non Alphanumerical Flags from 2.0. +// V2.1 - Shortened the source by adding .for loops & Updated the header and some comments. +// Added "simultaneous keypress" check. +// V2.0 - Added return of non-Alphanumeric keys into X & Y-Registers. +// Small optimizations here and there. +// V1.1 - Unrolled code to make it faster and optimized other parts of it. +// Removed SHIFT LOCK scanning. +// V1.0 - First Working Version along with test tool. -;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - ;; // ZERO PAGE Varibles - ;; $250-$258 is the 81st - 88th characters in BASIC input, a carry over from VIC-20 - ;; and not used on C64, so safe for us to use, probably. - ;; (Compute's Mapping the 64 p51) - .alias ScanResult $250 ;// 8 bytes - ;; Other variables are in RS232 ZP locations for now - ;; (Carefully avoiding $A7 which is used by 64NET) - .alias BufferNew $A9 ;// 3 bytes - .alias KeyQuantity $A8 ;// 1 byte - .alias TempZP $B6 ;// 1 byte + // // ZERO PAGE Varibles + // $250-$258 is the 81st - 88th characters in BASIC input, a carry over from VIC-20 + // and not used on C64, so safe for us to use, probably. + // (Compute's Mapping the 64 p51) + .label ScanResult = $250 // 8 bytes + // Other variables are in RS232 ZP locations for now + // (Carefully avoiding $A7 which is used by 64NET) + .label BufferNew = $A9 // 3 bytes + .label KeyQuantity = $A8 // 1 byte + .label TempZP = $B6 // 1 byte - ;; Reuse RS232 variables, since they should not be used - ;; by other things - ;; These are initialised in cinit all to $FF - .alias BufferOld $293 ; 3 bytes - .alias Buffer $297 ; 4 bytes - .alias BufferQuantity $B4 ; 1 byte + // Reuse RS232 variables, since they should not be used + // by other things + // These are initialised in cinit all to $FF + .label BufferOld = $293 // 3 bytes + .label Buffer = $297 // 4 bytes + .label BufferQuantity = $B4 // 1 byte - - ;// Operational Variables - .alias MaxKeyRollover 3 + // Operational Variables + .const MaxKeyRollover = 3 -scnkey: +SCNKEY: lda #$00 sta BufferQuantity - ;; Decrement key repeat timeout if non-zero + // Decrement key repeat timeout if non-zero ldx key_repeat_counter beq sk_start dec key_repeat_counter sk_start: - ;; Call main keyboard scanning routine + // Call main keyboard scanning routine jsr Main lda BufferQuantity beq no_keys_waiting - ;; Stuff each key pressed into the keyboard buffer + // Stuff each key pressed into the keyboard buffer ldy #$00 -* +!: lda Buffer,y jsr accept_key iny cpy BufferQuantity - bne - + bne !- no_keys_waiting: rts accept_key: - ;; Work out what is new and needs to be added - ;; to the input buffer. - ;; Also update the bucky key status flags etc + // Work out what is new and needs to be added + // to the input buffer. + // Also update the bucky key status flags etc cmp #$ff beq sk_nokey - ;; Got a key, turn it from matrix position to key value, - ;; and stuff it in the keyboard buffer + // Got a key, turn it from matrix position to key value, + // and stuff it in the keyboard buffer - ;; Convert matrix position to key code - ;; XXX - Add offset of $40, $80 or $C0 if shift, CONTROL or C= are held down + // Convert matrix position to key code + // XXX - Add offset of $40, $80 or $C0 if shift, CONTROL or C= are held down pha lda key_bucky_state and #$7 @@ -119,10 +118,10 @@ accept_key: ora keyboard_matrix_lookup,x tax lda keyboard_matrixes,x - ;; But don't insert $00 characters + // But don't insert $00 characters beq sk_nokey - ;; Stash key into keyboard buffer + // Stash key into keyboard buffer ldx keys_in_key_buffer cpx key_buffer_size beq sk_nokey @@ -134,8 +133,8 @@ sk_nokey: rts - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Routine for Scanning a Matrix Row + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Routine for Scanning a Matrix Row KeyInRow: ldy #7 @@ -151,18 +150,18 @@ nokey: rts - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Routine for handling: Key Found + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Routine for handling: Key Found KeyFound: stx TempZP dec KeyQuantity bmi OverFlow - ;; Originally, we resolved the keys. - ;; Now we just return the matrix position, so that - ;; we can do C64-style bucky modifications as normal - ;; was: ldy KeyTable,x + // Originally, we resolved the keys. + // Now we just return the matrix position, so that + // we can do C64-style bucky modifications as normal + // was: ldy KeyTable,x pha txa @@ -172,15 +171,15 @@ KeyFound: ldx TempZP rts - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Routine for handling: Overflow + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Routine for handling: Overflow OverFlow: - pla ;// Dirty hack to handle 2 layers of JSR + pla // Dirty hack to handle 2 layers of JSR pla pla pla - ;// Don't manipulate last legal buffer as the routine will fix itself once it gets valid input again. + // Don't manipulate last legal buffer as the routine will fix itself once it gets valid input again. TooManyNewKeys: ReturnNoKeys: @@ -190,21 +189,21 @@ ReturnNoKeys: lda #$FF sta last_key_matrix_position ldx #MaxKeyRollover-1 -* +!: sta Buffer,x sta BufferOld,x dex - bpl - + bpl !- rts - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Exit Routine for: No Activity + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Exit Routine for: No Activity NoActivityDetected: - ;; So cancel all bucky keys + // So cancel all bucky keys lda key_bucky_state sta key_last_bucky_state lda #$00 @@ -212,25 +211,25 @@ NoActivityDetected: jmp ReturnNoKeys - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Configure Data Direction Registers + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Configure Data Direction Registers Main: - ;; Begin with no key events + // Begin with no key events lda #$ff sta BufferNew+0 sta BufferNew+1 sta BufferNew+2 ldx #$ff - stx $dc02 ;// Port A - Output + stx $dc02 // Port A - Output ldy #$00 - sty $dc03 ;// Port B - Input + sty $dc03 // Port B - Input - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Check for Port Activity + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Check for Port Activity - sty $dc00 ;// Connect all Keyboard Rows + sty $dc00 // Connect all Keyboard Rows cpx $dc01 bne skip0 @@ -238,69 +237,69 @@ Main: JoystickActivity: - ;; Clear bucky key status + // Clear bucky key status lda #$00 sta key_bucky_state lda $dc01 and #$03 cmp #$01 - bne + - ;; down - ldx #$07 ; UP/DOWN + bne !+ + // down + ldx #$07 // UP/DOWN jsr KeyFound -* +!: cmp #$02 - bne + - ;; Up - ;; Mark shift as pressed + bne !+ + // Up + // Mark shift as pressed ldx #$01 stx key_bucky_state - ldx #$07 ; UP/DOWN + ldx #$07 // UP/DOWN jsr KeyFound -* - ;; Only allow up/down OR left/right, since - ;; else we have confusing situation with SHIFT required - ;; for one, but not the other. - ;; XXX - We could fix this by making the joystick activity - ;; feed the key input at a higher level, rather than - ;; simulating directly pressing the cursor keys. +!: + // Only allow up/down OR left/right, since + // else we have confusing situation with SHIFT required + // for one, but not the other. + // XXX - We could fix this by making the joystick activity + // feed the key input at a higher level, rather than + // simulating directly pressing the cursor keys. cmp #$03 - beq + + beq !+ jmp skdone -* +!: lda $dc01 and #$0c cmp #$04 - bne + + bne !+ ldx #$02 - jsr KeyFound ; LEFT/RIGHT -* + jsr KeyFound // LEFT/RIGHT +!: cmp #$08 - bne + + bne !+ ldx #$01 stx key_bucky_state ldx #$02 - jsr KeyFound ; LEFT/RIGHT -* + jsr KeyFound // LEFT/RIGHT +!: jmp skdone - - + + skip0: - ;; // Set max keys allowed before ignoring result + // // Set max keys allowed before ignoring result lda #MaxKeyRollover sta KeyQuantity - - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Check for Control Port #1 Activity - stx $dc00 ;// Disconnect all Keyboard Rows - cpx $dc01 ;// Only Control Port activity will be detected + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Check for Control Port #1 Activity + + stx $dc00 // Disconnect all Keyboard Rows + cpx $dc01 // Only Control Port activity will be detected bne JoystickActivity - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Scan Keyboard Matrix + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Scan Keyboard Matrix ldx #7 lda #%11111110 @@ -311,44 +310,44 @@ next_row: sta ScanResult,x pla sec - rol + rol dex bpl next_row - ;; X gets back to $FF here, which is assumed below + // X gets back to $FF here, which is assumed below - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Check for Control Port #1 Activity (again) + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Check for Control Port #1 Activity (again) - stx $dc00 ;// Disconnect all Keyboard Rows - cpx $dc01 ;// Only Control Port activity will be detected - beq + + stx $dc00 // Disconnect all Keyboard Rows + cpx $dc01 // Only Control Port activity will be detected + beq !+ jmp ReturnNoKeys -* - ;; Make X = $00, assumed below +!: + // Make X = $00, assumed below inx - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Check and flag Non Alphanumeric Keys + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Check and flag Non Alphanumeric Keys - ;; Store de-bounce data for bucky keys - ;; (Compute's Mapping the 64, p58-59) + // Store de-bounce data for bucky keys + // (Compute's Mapping the 64, p58-59) lda key_bucky_state sta key_last_bucky_state - ;; Build bucky state + // Build bucky state lda #$00 sta key_bucky_state lda ScanResult+6 eor #%10000000 - and #%10000000 ;// Left shift + and #%10000000 // Left shift rol rol and #$01 ora key_bucky_state sta key_bucky_state - ;; Right shift + // Right shift lda ScanResult+1 eor #$10 lsr @@ -359,14 +358,14 @@ next_row: ora key_bucky_state sta key_bucky_state - ;; Control + // Control lda ScanResult+0 eor #$04 and #$04 ora key_bucky_state sta key_bucky_state - ;; Vendor key + // Vendor key lda ScanResult+0 eor #$ff lsr @@ -377,7 +376,7 @@ next_row: ora key_bucky_state sta key_bucky_state - ;; Chick for shift + Vendor + // Chick for shift + Vendor cmp #$03 bne no_case_toggle lda key_last_bucky_state @@ -393,108 +392,108 @@ next_row: no_case_toggle: - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Check for pressed key(s) + // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // // Check for pressed key(s) lda ScanResult+7 cmp #$ff beq sk6 - jsr KeyInRow + jsr KeyInRow sk6: - ldx #8 - lda ScanResult+6 - beq sk5 - jsr KeyInRow + ldx #8 + lda ScanResult+6 + beq sk5 + jsr KeyInRow sk5: - ldx #16 - lda ScanResult+5 - beq sk4 - jsr KeyInRow + ldx #16 + lda ScanResult+5 + beq sk4 + jsr KeyInRow sk4: - ldx #24 - lda ScanResult+4 - beq sk3 - jsr KeyInRow + ldx #24 + lda ScanResult+4 + beq sk3 + jsr KeyInRow sk3: - ldx #32 - lda ScanResult+3 - beq sk2 - jsr KeyInRow + ldx #32 + lda ScanResult+3 + beq sk2 + jsr KeyInRow sk2: - ldx #40 - lda ScanResult+2 - beq sk1 - jsr KeyInRow + ldx #40 + lda ScanResult+2 + beq sk1 + jsr KeyInRow sk1: - ldx #48 - lda ScanResult+1 - beq sk0 - jsr KeyInRow + ldx #48 + lda ScanResult+1 + beq sk0 + jsr KeyInRow sk0: - ldx #56 - lda ScanResult+0 - beq skdone - jsr KeyInRow + ldx #56 + lda ScanResult+0 + beq skdone + jsr KeyInRow skdone: - ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ;; // Key Scan Completed + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Key Scan Completed - ;; // Put any new key (not in old scan) into buffer - ldx #MaxKeyRollover-1 + // Put any new key (not in old scan) into buffer + ldx #MaxKeyRollover-1 ProcessPressedKeys: - ;; Check if the currently pressed key is continuing to be held down + // Check if the currently pressed key is continuing to be held down lda BufferNew,x - cmp #$ff - beq ConsiderNextKey - cmp BufferOld - beq KeyHeld - cmp BufferOld+1 - beq KeyHeld - cmp BufferOld+2 - beq KeyHeld + cmp #$ff + beq ConsiderNextKey + cmp BufferOld + beq KeyHeld + cmp BufferOld+1 + beq KeyHeld + cmp BufferOld+2 + beq KeyHeld RecordKeypress: - ;; // New Key Detected + // New Key Detected ldy BufferQuantity cpy #MaxKeyRollover - bcc + + bcc !+ jmp TooManyNewKeys -* +!: AcceptKeyEvent: - sta Buffer,y + sta Buffer,y iny sty BufferQuantity ConsiderNextKey: - dex - bpl ProcessPressedKeys + dex + bpl ProcessPressedKeys - ;; Copy new presses to old list + // Copy new presses to old list ldx #MaxKeyRollover-1 -* +!: lda BufferNew,x sta BufferOld,x dex - bpl - + bpl !- - ;; Return success and set of pressed keys + // Return success and set of pressed keys clc rts KeyHeld: - ;; The key in A is still held down. - ;; compare with key in last_key_matrix_position - ;; (Compute's Mapping the 64 p36-37) - ;; if different, reset repeat count down. + // The key in A is still held down. + // compare with key in last_key_matrix_position + // (Compute's Mapping the 64 p36-37) + // if different, reset repeat count down. - ;; Ignore bucky keys, so that repeat can work when a - ;; bucky is held down. + // Ignore bucky keys, so that repeat can work when a + // bucky is held down. cmp #15 beq BuckyHeld cmp #52 @@ -507,7 +506,7 @@ KeyHeld: cmp last_key_matrix_position beq SameKeyHeld - ;; Different key held + // Different key held sta last_key_matrix_position pha lda key_first_repeat_delay @@ -521,12 +520,12 @@ SameKeyHeld: lda key_repeat_counter bmi KeyCanRepeat bne KeyRepeatWait - ;; Count down ended, so repeat key now + // Count down ended, so repeat key now KeyCanRepeat: - ;; (Compute's Mapping the 64 p58) + // (Compute's Mapping the 64 p58) pha - lda #6-2 ; Fudge factor to match speed + lda #6-2 // Fudge factor to match speed sta key_repeat_counter pla pla diff --git a/c64/kernal/screen.s b/c64/kernal/screen.s index b2e793fc..6964d141 100644 --- a/c64/kernal/screen.s +++ b/c64/kernal/screen.s @@ -1,19 +1,19 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 295 -;; - [CM64] Compute's Mapping the Commodore 64 - page 215 -;; -;; CPU registers that has to be preserved (see [RG64]): .A -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 295 +// - [CM64] Compute's Mapping the Commodore 64 - page 215 +// +// CPU registers that has to be preserved (see [RG64]): .A +// -screen: +SCREEN: - ;; There are only 2 sane ways to implement this routine, - ;; I hope this one is different than what Commodore picked :) + // There are only 2 sane ways to implement this routine, + // I hope this one is different than what Commodore picked :) - ldy #25 ; 25 columns - ldx #40 ; 40 rows + ldy #25 // 25 columns + ldx #40 // 40 rows rts diff --git a/c64/kernal/second.s b/c64/kernal/second.s index d130cfc5..9072536d 100644 --- a/c64/kernal/second.s +++ b/c64/kernal/second.s @@ -1,23 +1,23 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 296 -;; - [CM64] Compute's Mapping the Commodore 64 - page 223/224 -;; - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 296 +// - [CM64] Compute's Mapping the Commodore 64 - page 223/224 +// - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -second: +SECOND: - ;; Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031), - ;; allowed channels are 0-15; report error if out of range + // Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031), + // allowed channels are 0-15; report error if out of range cmp #$10 - bcc + - jmp kernalerror_DEVICE_NOT_FOUND ; XXX find a better error message for wrong channel (create new one?) -* + bcc !+ + jmp kernalerror_DEVICE_NOT_FOUND // XXX find a better error message for wrong channel (create new one?) +!: ora #$60 jmp common_open_close_unlsn_second diff --git a/c64/kernal/set_pointer_to_current_screen_line.s b/c64/kernal/set_pointer_to_current_screen_line.s index 1dbb7349..c89ad621 100644 --- a/c64/kernal/set_pointer_to_current_screen_line.s +++ b/c64/kernal/set_pointer_to_current_screen_line.s @@ -1,22 +1,22 @@ - ;; Put the address of the screen current line - ;; into the pointer at $D1 (current_screen_line_ptr). - ;; It must take into account the screen line link table - ;; (Compute's Mapping the 64 p216) + // Put the address of the screen current line + // into the pointer at $D1 (current_screen_line_ptr). + // It must take into account the screen line link table + // (Compute's Mapping the 64 p216) set_pointer_to_current_screen_line: - ;; Get pointer to start of the screen - lda hibase + // Get pointer to start of the screen + lda HIBASE sta current_screen_line_ptr+1 lda #$00 sta current_screen_line_ptr+0 - ;; Now advance for the number of lines + // Now advance for the number of lines ldx current_screen_y sptcsl_l2: - ;; XXX - Should we read the columns per line from - ;; somewhere? + // XXX - Should we read the columns per line from + // somewhere? ldy #<40 - ;; Double line length if line is linked + // Double line length if line is linked lda screen_line_link_table,x bpl sptcsl_l1 ldy #<80 diff --git a/c64/kernal/setfls.s b/c64/kernal/setfls.s index ce6892a8..44c7ab8b 100644 --- a/c64/kernal/setfls.s +++ b/c64/kernal/setfls.s @@ -1,17 +1,17 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 297 -;; - [CM64] Compute's Mapping the Commodore 64 - page 238 -;; -;; CPU registers that has to be preserved (see [RG64]): .A, .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 297 +// - [CM64] Compute's Mapping the Commodore 64 - page 238 +// +// CPU registers that has to be preserved (see [RG64]): .A, .X, .Y +// -setfls: +SETFLS: - ;; There are 6 sane ways to implement this routine, - ;; I hope this one won't cause similarity to CBM code + // There are 6 sane ways to implement this routine, + // I hope this one won't cause similarity to CBM code sta current_logical_filenum sty current_secondary_address diff --git a/c64/kernal/setmsg.s b/c64/kernal/setmsg.s index fc20350e..87b1125f 100644 --- a/c64/kernal/setmsg.s +++ b/c64/kernal/setmsg.s @@ -1,13 +1,13 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 298 -;; - [CM64] Compute's Mapping the Commodore 64 - page 239 -;; -;; CPU registers that has to be preserved (see [RG64]): .A, .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 298 +// - [CM64] Compute's Mapping the Commodore 64 - page 239 +// +// CPU registers that has to be preserved (see [RG64]): .A, .X, .Y +// -setmsg: +SETMSG: sta MSGFLG rts diff --git a/c64/kernal/setnam.s b/c64/kernal/setnam.s index 0cbead31..78033a3c 100644 --- a/c64/kernal/setnam.s +++ b/c64/kernal/setnam.s @@ -1,17 +1,17 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 298/299 -;; - [CM64] Compute's Mapping the Commodore 64 - page 238 -;; -;; CPU registers that has to be preserved (see [RG64]): .A, .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 298/299 +// - [CM64] Compute's Mapping the Commodore 64 - page 238 +// +// CPU registers that has to be preserved (see [RG64]): .A, .X, .Y +// -setnam: +SETNAM: - ;; There are 6 sane ways to implement this routine, - ;; I hope this one won't cause similarity to CBM code + // There are 6 sane ways to implement this routine, + // I hope this one won't cause similarity to CBM code sta FNLEN sty FNADDR + 1 diff --git a/c64/kernal/settim.s b/c64/kernal/settim.s index 7cfb3f11..0bceeaf8 100644 --- a/c64/kernal/settim.s +++ b/c64/kernal/settim.s @@ -1,27 +1,27 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 299/300 -;; - [CM64] Compute's Mapping the Commodore 64 - page 232 -;; -;; CPU registers that has to be preserved (see [RG64]): .A, .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 299/300 +// - [CM64] Compute's Mapping the Commodore 64 - page 232 +// +// CPU registers that has to be preserved (see [RG64]): .A, .X, .Y +// -settim: +SETTIM: - ;; Disable interrupts for the duration of the routine, to prevent - ;; jiffy clock update while changing it's values + // Disable interrupts for the duration of the routine, to prevent + // jiffy clock update while changing it's values sei - ;; Store the jiffy clock state + // Store the jiffy clock state sty TIME + 0 stx TIME + 1 sta TIME + 2 - ;; Enable interrupts. More elegant solution would be pha + sei + ... + pla, - ;; but (checked by running a test program) original ROM routine always - ;; leaves IRQs enabled. + // Enable interrupts. More elegant solution would be pha + sei + ... + pla, + // but (checked by running a test program) original ROM routine always + // leaves IRQs enabled. cli rts diff --git a/c64/kernal/settmo.s b/c64/kernal/settmo.s index 23cda2b0..16f84c40 100644 --- a/c64/kernal/settmo.s +++ b/c64/kernal/settmo.s @@ -1,13 +1,13 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 300 -;; - [CM64] Compute's Mapping the Commodore 64 - page 239 -;; -;; CPU registers that has to be preserved (see [RG64]): .A, .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 300 +// - [CM64] Compute's Mapping the Commodore 64 - page 239 +// +// CPU registers that has to be preserved (see [RG64]): .A, .X, .Y +// -settmo: +SETTMO: sta TIMOUT rts diff --git a/c64/kernal/talk.s b/c64/kernal/talk.s index 16440aa8..556de7d9 100644 --- a/c64/kernal/talk.s +++ b/c64/kernal/talk.s @@ -1,30 +1,30 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 301/302 -;; - [CM64] Compute's Mapping the Commodore 64 - page 223 -;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc -;; - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 301/302 +// - [CM64] Compute's Mapping the Commodore 64 - page 223 +// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc +// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -talk: +TALK: - ;; According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer + // According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer jsr iec_tx_flush - ;; Check whether device number is correct + // Check whether device number is correct jsr iec_check_devnum - bcc + + bcc !+ jmp kernalerror_DEVICE_NOT_FOUND -* - ;; Encode and execute the command +!: + // Encode and execute the command ora #$40 -common_talk_listen: ; common part of TALK and LISTEN +common_talk_listen: // common part of TALK and LISTEN sta IEC_TMP2 jmp iec_tx_command diff --git a/c64/kernal/tksa.s b/c64/kernal/tksa.s index be048d62..cd905edb 100644 --- a/c64/kernal/tksa.s +++ b/c64/kernal/tksa.s @@ -1,23 +1,23 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 302 -;; - [CM64] Compute's Mapping the Commodore 64 - page 224 -;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 302 +// - [CM64] Compute's Mapping the Commodore 64 - page 224 +// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -tksa: +TKSA: - ;; Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031), - ;; allowed channels are 0-15; report error if out of range + // Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031), + // allowed channels are 0-15; report error if out of range cmp #$10 - bcc + - jmp kernalerror_DEVICE_NOT_FOUND ; XXX find a better error message for wrong channel (create new one?) -* + bcc !+ + jmp kernalerror_DEVICE_NOT_FOUND // XXX find a better error message for wrong channel (create new one?) +!: ora #$F0 jmp common_untlk_tksa diff --git a/c64/kernal/udtim.s b/c64/kernal/udtim.s index 28af8cc4..9fce89a2 100644 --- a/c64/kernal/udtim.s +++ b/c64/kernal/udtim.s @@ -1,17 +1,17 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 303 -;; - [CM64] Compute's Mapping the Commodore 64 - page 232 -;; -;; CPU registers that has to be preserved (see [RG64]): .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 303 +// - [CM64] Compute's Mapping the Commodore 64 - page 232 +// +// CPU registers that has to be preserved (see [RG64]): .Y +// -udtim: +UDTIM: - ;; Update jiffy clock. The whole day is $4F1A00 jiffies (24 hours * 60 minutes * 60 seconds * 60 jiffies), - ;; after this time we have to reset the clock. + // Update jiffy clock. The whole day is $4F1A00 jiffies (24 hours * 60 minutes * 60 seconds * 60 jiffies), + // after this time we have to reset the clock. inc TIME+0 bne udtim_clock_done @@ -19,29 +19,29 @@ udtim: bne udtim_clock_rollover inc TIME+2 - ;; FALLTROUGH + // FALLTROUGH udtim_clock_done: -udtim_update_stkey: ; entry to be used when interrupts are disabled +udtim_update_stkey: // entry to be used when interrupts are disabled - ;; Another action we have to perform is to copy the last row of keyboard to RAM, - ;; so that various routines can detect the STOP key press - ;; XXX scnkey contains similar sequence - deduplicate this! + // Another action we have to perform is to copy the last row of keyboard to RAM, + // so that various routines can detect the STOP key press + // XXX scnkey contains similar sequence - deduplicate this! lda #$FF - sta CIA1_DDRA ; output + sta CIA1_DDRA // output lda #$00 - sta CIA1_DDRB ; input + sta CIA1_DDRB // input lda #$7F - sta CIA1_PRA ; select the last row (bit to 0) + sta CIA1_PRA // select the last row (bit to 0) - lda CIA1_PRB ; read the row + lda CIA1_PRB // read the row sta STKEY rts udtim_clock_rollover: - ;; At this point TIME+0 has to contain 0, + // At this point TIME+0 contains 0 lda TIME+1 cmp #$1A bne udtim_clock_done @@ -51,4 +51,4 @@ udtim_clock_rollover: lda #$00 sta TIME+2 sta TIME+1 - beq udtim_clock_done ; will always jump + beq udtim_clock_done // will always jump diff --git a/c64/kernal/under_rom_routines.s b/c64/kernal/under_rom_routines.s index 6162c15f..8a636f9f 100644 --- a/c64/kernal/under_rom_routines.s +++ b/c64/kernal/under_rom_routines.s @@ -1,19 +1,19 @@ - ;; IMPORTANT: - ;; These routines lengths cannot be changed without changing - ;; the aliases for peek_under_roms, poke_under_roms etc - ;; in ,aliases.s. - ;; Thus those addresses are expressed using formulae. +// IMPORTANT: +// These routines lengths cannot be changed without changing +// the aliases for peek_under_roms, poke_under_roms etc +// in ,aliases.s. +// Thus those addresses are expressed using formulae. install_ram_routines: - ;; Copy routines into place - ldx #ram_routines_len-1 -* + // Copy routines into place + ldx #ram_routines_end-ram_routines_start-1 +!: lda ram_routines_start,x sta tiny_nmi_handler,x dex - bpl - + bpl !- - ;; Point NMI handler to tiny_nmi_handler + // Point NMI handler to tiny_nmi_handler lda #tiny_nmi_handler @@ -28,7 +28,7 @@ tiny_nmi_handler_routine: rti peek_under_roms_routine: php - ; Offset of arg of lda ($00),y + // Offset of arg of lda ($00),y stx peek_under_roms+pa-peek_under_roms_routine+1 jsr memmap_allram pa: lda ($00),y @@ -38,7 +38,7 @@ pa: lda ($00),y poke_under_roms_routine: php - ; Offset of arg of lda ($00),y + // Offset of arg of lda ($00),y stx poke_under_roms+pb-poke_under_roms_routine+1 jsr memmap_allram pb: sta ($00),y @@ -60,7 +60,5 @@ memmap_allram_routine: sta $01 pla rts - + ram_routines_end: - .alias ram_routines_len ram_routines_end-ram_routines_start - diff --git a/c64/kernal/unlsn.s b/c64/kernal/unlsn.s index 0298c215..b37f7c26 100644 --- a/c64/kernal/unlsn.s +++ b/c64/kernal/unlsn.s @@ -1,22 +1,22 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 303 -;; - [CM64] Compute's Mapping the Commodore 64 - page 224 -;; - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc -;; - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 303 +// - [CM64] Compute's Mapping the Commodore 64 - page 224 +// - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc +// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -unlsn: +UNLSN: - ;; According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer + // According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer jsr iec_tx_flush - ;; Buffer empty, send the command + // Buffer empty, send the command lda #$3F jmp common_open_close_unlsn_second diff --git a/c64/kernal/untlk.s b/c64/kernal/untlk.s index e8054e0d..e1d5ba59 100644 --- a/c64/kernal/untlk.s +++ b/c64/kernal/untlk.s @@ -1,33 +1,33 @@ -;; -;; Official Kernal routine, described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 304 -;; - [CM64] Compute's Mapping the Commodore 64 - page 224 -;; - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc -;; - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf -;; -;; CPU registers that has to be preserved (see [RG64]): .X, .Y -;; +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 304 +// - [CM64] Compute's Mapping the Commodore 64 - page 224 +// - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc +// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +// +// CPU registers that has to be preserved (see [RG64]): .X, .Y +// -untlk: +UNTLK: - ;; According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer + // According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer jsr iec_tx_flush - ;; Buffer empty, send the command + // Buffer empty, send the command lda #$5F -common_untlk_tksa: ; common part of UNTLK and TKSA +common_untlk_tksa: // common part of UNTLK and TKSA sta IEC_TMP2 jsr iec_tx_command - bcs + ; branch if error - ;; XXX - for TKSA, is it really the right place to do a turnaround? I've got some doubts - ;; (it forces us to send the TKSA command 'manually' sometimes), but - ;; Luigi Di Fraia (https://luigidifraia.wordpress.com/2017/06/27/codebase64-on-the-kernal-behaviour/) - ;; claims TKSA Kernal routine actually does the turnaround + bcs !+ // branch if error + // XXX - for TKSA, is it really the right place to do a turnaround? I've got some doubts + // (it forces us to send the TKSA command 'manually' sometimes), but + // Luigi Di Fraia (https://luigidifraia.wordpress.com/2017/06/27/codebase64-on-the-kernal-behaviour/) + // claims TKSA Kernal routine actually does the turnaround jmp iec_turnaround_to_listen -* +!: rts diff --git a/c64/kernal/vector_defaults.s b/c64/kernal/vector_defaults.s index fc35e4ac..dd7fa89d 100644 --- a/c64/kernal/vector_defaults.s +++ b/c64/kernal/vector_defaults.s @@ -1,26 +1,26 @@ -;; -;; Default values for Kernal vectors - described in: -;; -;; - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR) -;; - [CM64] Compute's Mapping the Commodore 64 - page 237 -;; +// +// Default values for Kernal vectors - described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR) +// - [CM64] Compute's Mapping the Commodore 64 - page 237 +// vector_defaults: - .word default_irq_handler ;; CINV - .word default_brk_handler ;; CBINV - .word default_nmi_handler ;; NMINV + .word default_irq_handler // CINV + .word default_brk_handler // CBINV + .word default_nmi_handler // NMINV - .word open ;; IOPEN - .word close ;; ICLOSE - .word chkin ;; ICHKIN - .word ckout ;; ICKOUT - .word clrchn ;; ICLRCH - .word chrin ;; IBASIN - .word chrout ;; IBSOUT - .word stop ;; ISTOP - .word getin ;; IGETIN - .word clall ;; ICLALL - .word default_brk_handler ;; USRCMD - .word load ;; ILOAD - .word save ;; ISAVE + .word OPEN // IOPEN + .word CLOSE // ICLOSE + .word CHKIN // ICHKIN + .word CKOUT // ICKOUT + .word CLRCHN // ICLRCH + .word CHRIN // IBASIN + .word CHROUT // IBSOUT + .word STOP // ISTOP + .word GETIN // IGETIN + .word CLALL // ICLALL + .word default_brk_handler // USRCMD + .word LOAD // ILOAD + .word SAVE // ISAVE diff --git a/c64/program_traces/README.md b/c64/program_traces/README.md index 81ee2152..451dddbe 100644 --- a/c64/program_traces/README.md +++ b/c64/program_traces/README.md @@ -7,6 +7,6 @@ C64 KERNAL. To collect a program trace: x64 -remotemonitor & -src/collect_data localhost 6510 | tee logfile +build/tools/collect_data localhost 6510 | tee logfile diff --git a/src/compress_text.c b/src/compress_text.c index 576d4d09..ff0cc4eb 100644 --- a/src/compress_text.c +++ b/src/compress_text.c @@ -251,7 +251,7 @@ int calc_stats(const char *s) if (s[j]==char_freqs[char_num].c) break; if (s[j]&0x80) fprintf(stderr,"Word '%s' contains funny char 0x%02x\n",s,s[j]); if (char_num>MAX_CHARS) { - fprintf(stderr,"Too many unique characters in message list. Max is %d\n",MAX_CHARS); + fprintf(stderr,"Too many unique characters in message list. Max is %d\n",MAX_CHARS); exit(-1); } if (char_num>=char_max) char_max=char_num+1; @@ -438,7 +438,7 @@ int main(void) printf("packed_message_chars:\n"); for(int i=0;id_name)>2) { - if (de->d_name[0]!='.'&&de->d_name[0]!='#') // ignore temp files etc - if (!strcmp(&de->d_name[strlen(de->d_name)-2],".s")) { - if (strcmp(de->d_name,"combined.s")) { - if (source_count>=MAX_FILES) DO_ERROR("Too many source files. Increase MAX_FILES?"); - source_files[source_count].file=strdup(de->d_name); - source_files[source_count].address=-1; - source_count++; - } - } + if (de->d_name[0]!='.'&&de->d_name[0]!='#') // ignore temp files etc + if (!strcmp(&de->d_name[strlen(de->d_name)-2],".s")) { + if (strcmp(de->d_name,"combined.s")) { + if (source_count>=MAX_FILES) DO_ERROR("Too many source files. Increase MAX_FILES?"); + source_files[source_count].file=strdup(de->d_name); + source_files[source_count].label=strdup(de->d_name); + for (char *charptr = source_files[source_count].label; *charptr != 0; charptr++) { + if (*charptr == '.') *charptr = '_'; // KickAss does not like full stops in labels + } + source_files[source_count].address=-1; + source_count++; + } + } } } if (retVal) break; @@ -119,7 +124,7 @@ int main(int argc,char **argv) if (sscanf(source_files[i].file,"%x.%[^.]",&addr,funcname)==2) { // Function must appear at specific address source_files[i].address=addr; - printf("function '%s' should be placed at $%04X\n",funcname,addr); + // printf("function '%s' should be placed at $%04X\n",funcname,addr); } } @@ -133,56 +138,54 @@ int main(int argc,char **argv) fprintf(stderr,"Sorted.\n"); - for(int i=0;i Date: Sat, 7 Sep 2019 12:38:58 +0200 Subject: [PATCH 5/9] changed Kernal revision to avoid conflicts with some other ROMs --- c64/kernal/ff80.kernal_revision.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c64/kernal/ff80.kernal_revision.s b/c64/kernal/ff80.kernal_revision.s index ff387fe3..0aad2a67 100644 --- a/c64/kernal/ff80.kernal_revision.s +++ b/c64/kernal/ff80.kernal_revision.s @@ -60,4 +60,4 @@ // kernal_revision: - .byte $FF // XXX possibly change this value (current candidate: $F0), $FF conflicts with other machines + .byte $F0 // chosen not to conflict with anything known so far From b9e3cb89bfd45b0635d93e6316ab87ee4cf0a376 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Sun, 8 Sep 2019 22:17:49 +0200 Subject: [PATCH 6/9] new routine binning tool - modified dynamic knapsack solving algorithm --- .gitignore | 3 - Makefile | 197 +++--- bin/{REEADME.txt => README.txt} | 0 bin/basic_generic.rom | Bin 8192 -> 8192 bytes bin/basic_mega65.rom | Bin 8192 -> 8192 bytes bin/basic_ultimate64.rom | Bin 8192 -> 8192 bytes bin/kernal_generic.rom | Bin 8192 -> 8192 bytes bin/kernal_mega65.rom | Bin 8192 -> 8192 bytes bin/kernal_ultimate64.rom | Bin 8192 -> 8192 bytes src/build_segment.cc | 983 +++++++++++++++++++++++++++ src/compress_text.c | 2 +- src/{ => outdated}/basic005.c | 0 src/{ => outdated}/prepare_startup.c | 0 src/{ => outdated}/preprocess.c | 0 14 files changed, 1084 insertions(+), 101 deletions(-) rename bin/{REEADME.txt => README.txt} (100%) create mode 100644 src/build_segment.cc rename src/{ => outdated}/basic005.c (100%) rename src/{ => outdated}/prepare_startup.c (100%) rename src/{ => outdated}/preprocess.c (100%) diff --git a/.gitignore b/.gitignore index ffd89384..d9f921e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # Compilation related files -temp.s -temp.sym - assembler/KickAss* build/* diff --git a/Makefile b/Makefile index 5080e7ed..66226086 100644 --- a/Makefile +++ b/Makefile @@ -1,27 +1,41 @@ # Source files -SRC_COMMON = $(wildcard c64/aliases/*.s) -SRC_BASIC_COMMON = $(SRC_COMMON) $(wildcard c64/basic/*.s) -SRC_KERNAL_COMMON = $(SRC_COMMON) $(wildcard c64/kernal/*.s c64/kernal/jumptable/*.s c64/kernal/iec/*.s c64/kernal/interrupts/*.s) +SRCDIR_COMMON = c64/aliases +SRCDIR_BASIC_COMMON = $(SRCDIR_COMMON) c64/basic +SRCDIR_KERNAL_COMMON = $(SRCDIR_COMMON) c64/kernal c64/kernal/jumptable c64/kernal/iec c64/kernal/interrupts -SRC_BASIC_generic = $(SRC_BASIC_COMMON) $(wildcard c64/basic/,target_generic/*.s) -SRC_BASIC_mega65 = $(SRC_BASIC_COMMON) $(wildcard c64/basic/,target_mega65/*.s) -SRC_BASIC_ultimate64 = $(SRC_BASIC_COMMON) $(wildcard c64/basic/,target_ultimate64/*.s) +SRCDIR_BASIC_generic = $(SRCDIR_BASIC_COMMON) c64/basic/,target_generic +SRCDIR_BASIC_mega65 = $(SRCDIR_BASIC_COMMON) c64/basic/,target_mega65 +SRCDIR_BASIC_ultimate64 = $(SRCDIR_BASIC_COMMON) c64/basic/,target_ultimate64 -SRC_KERNAL_generic = $(SRC_KERNAL_COMMON) $(wildcard c64/kernal/,target_generic/*.s) -SRC_KERNAL_mega65 = $(SRC_KERNAL_COMMON) $(wildcard c64/kernal/,target_mega65/*.s) -SRC_KERNAL_ultimate64 = $(SRC_KERNAL_COMMON) $(wildcard c64/kernal/,target_ultimate64/*.s) +SRCDIR_KERNAL_generic = $(SRCDIR_KERNAL_COMMON) c64/kernal/,target_generic +SRCDIR_KERNAL_mega65 = $(SRCDIR_KERNAL_COMMON) c64/kernal/,target_mega65 +SRCDIR_KERNAL_ultimate64 = $(SRCDIR_KERNAL_COMMON) c64/kernal/,target_ultimate64 + +SRC_TOOLS = $(wildcard src/tools/*.c,src/tools/*.cc) # List of tools -TOOL_COLLECT_DATA = build/tools/collect_data -TOOL_COMPRESS_TEXT = build/tools/compress_text -TOOL_PNGPREPARE = build/tools/pngprepare -TOOL_PREPROCESS = build/tools/preprocess -TOOL_SIMILARITY = build/tools/similarity +TOOL_COLLECT_DATA = build/tools/collect_data +TOOL_COMPRESS_TEXT = build/tools/compress_text +TOOL_PNGPREPARE = build/tools/pngprepare +TOOL_BUILD_SEGMENT = build/tools/build_segment +TOOL_SIMILARITY = build/tools/similarity +TOOL_ASSEMBLER = assembler/KickAss.jar -TOOLS_LIST = $(TOOL_COLLECT_DATA) $(TOOL_COMPRESS_TEXT) $(TOOL_PNGPREPARE) $(TOOL_PREPROCESS) $(TOOL_SIMILARITY) +TOOLS_LIST = $(pathsubst src/tools/%,build/tools/%,$(basename $(SRC_TOOLS))) + +# List of targets + +STD_TARGET_LIST = build/kernal_generic.rom build/basic_generic.rom \ + build/kernal_mega65.rom build/basic_mega65.rom \ + build/kernal_ultimate64.rom build/basic_ultimate64.rom \ + build/chargen.rom + +EXT_TARGET_LIST = build/newc65.rom + +REL_TARGET_LIST = $(pathsubst build/%,bin/%, $(STD_TARGET_LIST)) # GIT commit @@ -31,126 +45,115 @@ GIT_COMMIT:= $(shell git log -1 --pretty='%h' | tr '[:lower:]' '[:upper:]') .PHONY: all clean updatebin -all: build/chargen build/newkern_generic build/newbasic_generic build/newc65 build/newkern_ultimate64 build/newbasic_ultimate64 +all: $(STD_TARGET_LIST) $(EXT_TARGET_LIST) clean: @rm -rf build - @rm -f temp.s - @rm -f temp.sym -updatebin: build/chargen build/newbasic_generic build/newkern_generic build/newbasic_mega65 build/newkern_mega65 build/newbasic_ultimate64 build/newkern_ultimate64 - cp build/chargen bin/chargen.rom - cp build/newbasic_generic bin/basic_generic.rom - cp build/newkern_generic bin/kernal_generic.rom - cp build/newbasic_mega65 bin/basic_mega65.rom - cp build/newkern_mega65 bin/kernal_mega65.rom - cp build/newbasic_ultimate64 bin/basic_ultimate64.rom - cp build/newkern_ultimate64 bin/kernal_ultimate64.rom +updatebin: $(STD_TARGET_LIST) + cp build/chargen.rom bin/chargen.rom + cp build/basic_generic.rom bin/basic_generic.rom + cp build/kernal_generic.rom bin/kernal_generic.rom + cp build/basic_mega65.rom bin/basic_mega65.rom + cp build/kernal_mega65.rom bin/kernal_mega65.rom + cp build/basic_ultimate64.rom bin/basic_ultimate64.rom + cp build/kernal_ultimate64.rom bin/kernal_ultimate64.rom # Rules - tools -$(TOOL_COLLECT_DATA): src/collect_data.c Makefile +$(TOOL_PNGPREPARE): src/pngprepare.c Makefile @mkdir -p build/tools - gcc -Wall -o $(TOOL_COLLECT_DATA) src/collect_data.c + $(CC) -O2 -Wall -I/usr/local/include -L/usr/local/lib -o $@ $< -lpng $(TOOL_COMPRESS_TEXT): src/compress_text.c Makefile @mkdir -p build/tools - gcc -g -Wall -o $(TOOL_COMPRESS_TEXT) src/compress_text.c -lm + $(CC) -O2 -Wall -I/usr/local/include -L/usr/local/lib -o $@ $< -lm -$(TOOL_PNGPREPARE): src/pngprepare.c Makefile +build/tools/%: src/%.c Makefile @mkdir -p build/tools - $(CC) $(COPT) -I/usr/local/include -L/usr/local/lib -o $(TOOL_PNGPREPARE) src/pngprepare.c -lpng + $(CC) -O2 -Wall -o $@ $< -$(TOOL_PREPROCESS): src/preprocess.c Makefile +build/tools/%: src/%.cc Makefile @mkdir -p build/tools - gcc -g -Wall -o $(TOOL_PREPROCESS) src/preprocess.c - -$(TOOL_SIMILARITY): src/similarity.c Makefile - @mkdir -p build/tools - gcc -g -Wall -o $(TOOL_SIMILARITY) src/similarity.c + $(CXX) -O2 -Wall -o $@ $< # Rules - CHARGEN -build/chargen: $(TOOL_PNGPREPARE) assets/8x8font.png - $(TOOL_PNGPREPARE) charrom assets/8x8font.png build/chargen +build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png + $(TOOL_PNGPREPARE) charrom assets/8x8font.png build/chargen.rom -# Dependencies +# Dependencies - BASIC and KERNAL -build/basic_generic/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_generic) build/basic/packed_messages.s -build/kernal_generic/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_generic) -build/newrom_generic: build/basic_generic/OUT.BIN build/kernal_generic/OUT.BIN -build/newkern_generic: build/newrom_generic Makefile -build/newbasic_generic: build/newrom_generic Makefile +build/target_generic/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_generic) $(foreach dir,$(SRCDIR_BASIC_generic),$(wildcard $(dir)/*.s)) build/,generated/gen_packed_messages.s +build/target_mega65/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_mega65) $(foreach dir,$(SRCDIR_BASIC_mega65),$(wildcard $(dir)/*.s)) build/,generated/gen_packed_messages.s +build/target_ultimate64/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_ultimate64) $(foreach dir,$(SRCDIR_BASIC_ultimate64),$(wildcard $(dir)/*.s)) build/,generated/gen_packed_messages.s -build/basic_mega65/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_mega65) build/basic/packed_messages.s -build/kernal_mega65/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_mega65) -build/newrom_mega65: build/basic_mega65/OUT.BIN build/kernal_mega65/OUT.BIN -build/newkern_mega65: build/newrom_mega65 Makefile -build/newbasic_mega65: build/newrom_mega65 Makefile +build/target_generic/OUTK.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_KERNAL_generic) $(foreach dir,$(SRCDIR_KERNAL_generic),$(wildcard $(dir)/*.s)) +build/target_mega65/OUTK.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_KERNAL_mega65) $(foreach dir,$(SRCDIR_KERNAL_mega65),$(wildcard $(dir)/*.s)) +build/target_ultimate64/OUTK.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_KERNAL_ultimate64) $(foreach dir,$(SRCDIR_KERNAL_ultimate64),$(wildcard $(dir)/*.s)) -build/basic_ultimate64/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_ultimate64) build/basic/packed_messages.s -build/kernal_ultimate64/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_ultimate64) -build/newrom_ultimate64: build/basic_ultimate64/OUT.BIN build/kernal_ultimate64/OUT.BIN -build/newkern_ultimate64: build/newrom_ultimate64 Makefile -build/newbasic_ultimate64: build/newrom_ultimate64 Makefile +build/target_generic/newrom: build/target_generic/OUTB.BIN build/target_generic/OUTK.BIN +build/target_mega65/newrom: build/target_mega65/OUTB.BIN build/target_mega65/OUTK.BIN +build/target_ultimate64/newrom: build/target_ultimate64/OUTB.BIN build/target_ultimate64/OUTK.BIN +build/kernal_generic.rom: build/target_generic/newrom +build/kernal_mega65.rom: build/target_mega65/newrom +build/kernal_ultimate64.rom: build/target_ultimate64/newrom + +build/basic_generic.rom: build/target_generic/newrom +build/basic_mega65.rom: build/target_mega65/newrom +build/basic_ultimate64.rom: build/target_ultimate64/newrom # Rules - BASIC and KERNAL -build/basic/packed_messages.s: $(TOOL_COMPRESS_TEXT) - @mkdir -p build/basic - $(TOOL_COMPRESS_TEXT) > build/basic/packed_messages.s +build/,generated/gen_packed_messages.s: $(TOOL_COMPRESS_TEXT) + @mkdir -p build/,generated + $(TOOL_COMPRESS_TEXT) > build/,generated/gen_packed_messages.s -.PRECIOUS: build/basic_%/OUT.BIN -build/basic_%/OUT.BIN: $(TOOLS_LIST) $(SRC_BASIC_$*) build/basic/packed_messages.s - @mkdir -p build/basic_$* - @rm -f build/basic_$*/* - @for SRC in $(SRC_BASIC_$*); do \ - ln -s ../../$$SRC build/basic_$*/$$(basename $$SRC); \ - done - @ln -s ../../build/basic/packed_messages.s build/basic_$*/packed_messages.s - $(TOOL_PREPROCESS) -d build/basic_$* -l a000 -h e4d2 +.PRECIOUS: build/target_%/OUTB.BIN +build/target_%/OUTB.BIN: + @mkdir -p build/target_$* + @rm -f $@* build/target_$*/BASIC* + @$(TOOL_BUILD_SEGMENT) -s BASIC -i BASIC-$* -o OUTB.BIN -t build/target_$* -l a000 -h e4d2 $(SRCDIR_BASIC_$*) build/,generated -.PRECIOUS: build/kernal_%/OUT.BIN -build/kernal_%/OUT.BIN: $(TOOLS_LIST) $(SRC_KERNAL_$*) - @mkdir -p build/kernal_$* - @rm -f build/kernal_$*/* - @for SRC in $(SRC_KERNAL_$*); do \ - ln -s ../../$$SRC build/kernal_$*/$$(basename $$SRC); \ - done - $(TOOL_PREPROCESS) -d build/kernal_$* -l e4d3 -h ffff +.PRECIOUS: build/target_%/OUTK.BIN +build/target_%/OUTK.BIN: + @mkdir -p build/target_$* + @rm -f $@* build/target_$*/KERNAL* + @$(TOOL_BUILD_SEGMENT) -s KERNAL -i KERNAL-$* -o OUTK.BIN -t build/target_$* -l e4d3 -h ffff $(SRCDIR_KERNAL_$*) -.PRECIOUS: build/newrom_% -build/newrom_%: build/basic_%/OUT.BIN build/kernal_%/OUT.BIN - cat build/basic_$*/OUT.BIN build/kernal_$*/OUT.BIN > build/newrom_$* +.PRECIOUS: build/target_%/newrom +build/target_%/newrom: + cat build/target_$*/OUTB.BIN build/target_$*/OUTK.BIN > $@ -.PRECIOUS: build/newkern_% -build/newkern_%: build/newrom_% Makefile - dd if=build/newrom_$* bs=8192 count=1 skip=2 of=build/newkern_$* +.PRECIOUS: build/kernal_%.rom +build/kernal_%.rom: + dd if=build/target_$*/newrom bs=8192 count=1 skip=2 of=$@ -.PRECIOUS: build/newbasic_% -build/newbasic_%: build/newrom_% Makefile - dd if=build/newrom_$* bs=8192 count=1 skip=0 of=build/newbasic_$* +.PRECIOUS: build/basic_%.rom +build/basic_%.rom: + dd if=build/target_$*/newrom bs=8192 count=1 skip=0 of=$@ # Rules - platform 'Mega 65' specific -build/newc65: build/newkern_mega65 build/newbasic_mega65 build/chargen Makefile - dd if=/dev/zero bs=4096 count=10 of=build/newc65 - cat build/newbasic_mega65 build/chargen build/chargen build/newkern_mega65 >> build/newc65 - dd if=/dev/zero bs=65536 count=1 of=build/basic/padding - cat build/basic/padding >> build/newc65 +build/newc65.rom: build/kernal_mega65.rom build/basic_mega65.rom build/chargen.rom Makefile + dd if=/dev/zero bs=4096 count=10 of=build/newc65.rom + cat build/basic_mega65.rom build/chargen.rom build/chargen.rom build/kernal_mega65.rom >> build/newc65.rom + dd if=/dev/zero bs=65536 count=1 of=build/padding + cat build/padding >> build/newc65.rom + rm -f build/padding # Rules - tests -test: build/newkern_generic build/newbasic_generic - x64 -kernal build/newkern_generic -basic build/newbasic_generic -8 empty.d64 +test: build/kernal_generic.rom build/basic_generic.rom + x64 -kernal build/kernal_generic.rom -basic build/basic_generic.rom -8 empty.d64 -testremote: build/newkern_generic build/newbasic_generic - x64 -kernal build/newkern_generic -basic build/newbasic_generic -remotemonitor +testremote: build/kernal_generic.rom build/basic_generic.rom + x64 -kernal build/kernal_generic.rom -basic build/basic_generic.rom -remotemonitor testm65: build/newc65 - m65 -b ../mega65-core/bin/mega65r1.bit -k ../mega65-core/bin/KICKUP.M65 -R build/newc65 -4 + m65 -b ../mega65-core/bin/mega65r1.bit -k ../mega65-core/bin/KICKUP.M65 -R build/newc65.rom -4 -testsimilarity: build/newrom_generic $(TOOL_SIMILARITY) - $(TOOL_SIMILARITY) kernal build/newrom_generic - $(TOOL_SIMILARITY) basic build/newrom_generic +testsimilarity: build/target_generic/newrom $(TOOL_SIMILARITY) + $(TOOL_SIMILARITY) kernal build/target_generic/newrom + $(TOOL_SIMILARITY) basic build/target_generic/newrom diff --git a/bin/REEADME.txt b/bin/README.txt similarity index 100% rename from bin/REEADME.txt rename to bin/README.txt diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index 71a7c830c8541bd840c0533b5aff008e0eefb3c0..966d794a1402a3a82ca753a7d6d084d97a429ce9 100644 GIT binary patch delta 1902 zcmYjSeQXp(6yJ{?d+oN}Yi;qQ&<56N*CUt(Y+E3iRG0xlK@<&nADfx=<(n^p|00C~|jRuv__v1-Q_0$b`l;NXjK`72>golZ#sw6H_v&NUz1n)KX* zJ^U0_rM%~wcWph|JkjQvB7q(6NC6Ts8E|%G$9NNI^8AYzS@LROkxSjy-`pX~`8$I~ zwJ8t*LI5$aE8t2M;>N)i;Rr`6~(IoQ9CsNwXnCiJ6G8#73go$IKXESgY22UgN# zmN_E6>owjT%~G>UE9|-E7RqtQoC>kv1Q@|LI^a91`)E_r^FaDY&dJ+C$7L~ZS#3Oa z*(;JIQXQ$3R;zUijZQNLWwK5hkJPZZR6&y}dL@pBRD}hezYUgX05T+Z<<2c@IHe7l zvyH)`lz(xP(?7Rq|nNU{C6&rf8kHei^mcoVl9Y$iPN}#iZPJMPMA{%ICN_OeKHVZ(F+5F`_^r< z=w$`7VaQ&q&PaQJ)=8@&XSFzN$$2@mpRXV%8M-a$xfQ@agxlKMat4E;KLg4laJJa5 zW_kN5diPp#lA4y849joj%wg_@<=r{k<@#)YBdej?94giDLt-#y34-(EE0jCUgByo! zhe|4hNQNyvoTiU@9%i%wNsioMBL9}XtdMXf<8!L+mUsvd-PPoe-7}YesX2!)HT;Jb zc3+_AY~dJ1kGnxGEd`8y+63VY+RjRXOj4&nSnhMz%-^Sld0Ti=3GdPzOQ3Lxvst`O zlZEW!;Pw&IGngM^6Yb()NzB#mZ5b64gC*v;PKl6ReXmw)0V2V0C!lL!DYtxY*1Bz(SDdPG`s!P2$(B16BL0(bt`iAqhB?pLWk@$}D-6yR^Qy z^Me{zPbsN{McMfmq!DNaIysm!|M7|K{`A?-L)DRV`vxKj^F}}~g8Yk7{UKm;M7})Z zSq5-9HDejGZA4zem8{q{0{lRvXL*HS2zEBu>JriS5$BKlB8hf?&+@c@=ty{5@}up3 z9Er$BT&seOy0JJ^Wz>W?=uQ?l>SV|)J>#Lf3uuW$D>ULZJdnaN3+>lKvo06VW*=}* z7t&DbV-$0{(ZAjuHOD3rmvYTXjZZ>Oo=W!L9jy>--l4`LD8eCK*_+;*bOJ)8fPfr; z=sUgLEBc(`|CNH;>4GAl-jp*;!2H3eu>i=4C`9Lh=yDT1t#&1h;&RMHk+sTc0;q)m~VE|4r#>qqfes1aC=-a7FStPFD@R2dV~73wkn`Y89NF!*kBi- z^C?q+F_AV6SxVrYQ4#E`R9j89(<4_?6XtEOuk)1FtBBw;_#@A9ZCE_1l92rkxRZGa ziiiEM52RrQh=I5sv}>*5J-9z5m-5e?{i)!&{IgcU?^!G^u;gIDf}lcW#$Qe%Lt#Ao zL^RYv-gE76HQ8xIJM;GrX_kt}yHYVs?OOwnu?h_n;~{F8Q{enU3oji;xP!!8J$8|b z;3*+JFc3%#md8)kA%A+OuW=w2EeDy*!!y^}InP;oQ6C+LKFIXr5(~Z{ANR~D@ITHMWmxv(BR}dl~;DI$>##KHvDjB1v!3;J{nsH*soHIR* zS;xst^kAD*+bHXDd)yvy+|`;?8(POi!_sN9Ft)!wwh zk-uqUVfyOU;`s}oDP3H$sBB9^eI24`!Xy#Kpnu84XfP2&3PTL33^AvXbYljwSZ9!# zB-3gmS&uwQ(zD4dSj;AK=8}0iBo~vs$L5pte6paxO$yOM!aPcf&?2(9n9M05rKF6M zlgBH_k_u8;^#oZ;s%yyXT4Gp6=9k}SZb$F#_q@9w)!WbteCk8t%_|Bj z(Nxw86X<{owYnxq>9iX)^{j{$qpL@X(d5?EXczh#Wvy$OoXGQ>o-sX*qE(wOp_e|( zvE>Oi;ZzGa0@ikXQ8ph2>>F!!q5XKgqI|Rc1=QMIWsN(fd)GSFU5_f!-5+64_0uV9 zTX;{9bghZ*p1v#4n=RHo^}t!GkTy4jn71lcTwSFY~g(LOLROMTUh4M zBi%g@#TLg(VvAyBu`RC%RVdaFtB=+7tg?4tcaukHIc@#a)6?3rUN|t0ayO~b8uYfk z(7wz5N$zU2-`>47A5HB+uSQYy4lMWo;%l^F{7zZE8%2il(RjJ&5)dAs6|5%XX_0+R zRFIae)M|9Lv)Un)z z;Lr5cjuACgu_xqi^0E~{T|tkSkmjZ%E|re#bxN-4TNLM#_TEAq>}nOFGVIcRsfJr7 z)pB*XD=gI;8saeEtjFIEhvNA9?43!#*02-U#Cm}S1G$(kM#3(w7>;cryW5LjlkhOX=ZJ@4_eeVbh<6atO1auTNa<4>`=W$P z!%~*Uuw_BXrkJdT5W`jmxwEXbS4IzUixzw_AxA*xS~MGekEj;>aRPJ<(IffnHLnvC zi0Dvx$}pnwC2~`p1O+nkofVv5Gnm8orLI}@&Vc06J^*v%bRYsn4p?^vM%mV&K)`-= z`l!$4-OCOW{!3F`G4d&kJS9rG#|Zv0Eb>X0)tsP}8k|9KM!eN8nG`EHSP;Y&K7Mt| zY_}i{4N;#s^+~q+lmHpxj>P;)f3SbXs8=_l+ENgsbA* zPMtk_X9n=HjeWQ&B=6HNvPQ${dI-egJ*WZ@zN#Re6qU!o!HS^d;(jgdb#w10K)RF3 znC@lI^+n!e1AUN%2hZZ(a46&9+~LlGuroT?76+?F$;O>wr}}(0ZZM|?K`#*ZmjVSv0SXv@-k3=j1o^AR9Cxn&2jz@pROxCbXfbhS zJ;Cy1FsxNFtFvxOMupNCnH0;hQ9SI|vBQ4WD0@w35S3y%hNuW=Pp|=^-=E-sQ!~n= zdY=28UK3D_yl!$T)=<9JteR8d7YC{)K9rnU+wb?9HOs>i*%N+U4M@9aguuPvm&_Uy zF@dNN8O3!v1@w8Ez~4)r&F?fg+WsWtNh6+;*~_v*t8*~yAAs)YoZIu)PN5KLdX_^> z%7)~AH5fRK?$c}y@PA91M?W9n(+tn@ujCd{Vg5w!?4-X05aM&pvvTln!XkqE9hz3s zHS1W5#~?n!4u|w>#n$!nIZ63jx}$wJ*#0x&Zjrn;^I5gsXkQdMsC_OKb z8gCbgPKMtZ!0s^n;{kyIoZ}D-flizr;3+0A_nQIVWpyD$AV1(Z>X7^3f}P}^c%#T2 z5D11#*2rLfIlUfS{|UXMIUM>!wo@rpEs{ln`;o0@nuRq4vz<6C2u4}-nyd7yMp!=& zoiDyE_xv8Jk|J%>(sVYJ!PF4&z{sc2dG59$y+wX72(m=eTiZsh)7;C>$p7)XEkztf z`?yGFs^K=+E8T|8?Kd3piYYJGZ*~Cli7F!I!Aftlng!cs{M1^Eq*`AM1VNsm7g$Jd zsIp7@#m&RsAm2*8^awcCi5rGQv!`qrFw_d z;E+t!*Nxeb{sDZoziZ<%b5;nffmDF5&R@)}M-muY=c|A5*np`(qBv4Ih*txmjxC!g&riS{-iR4rI6+x zhAj@VCB2E~7*bR9w+v)&{2|6anUi0jm)Bw~1-kVVl-Fu!w$pcZ%oL(UlT)0>LKv;R NY?IrYRghQ)k6IW{lvY~-DHLpyLWr*@Wd2AP2r{EhZl&D?jYH0G6Ui(52~C$$+7#m=t+(}l=1x=!nB9fd1n;Qik<|)+|6(g+2ozgUF{)zy)9&g z5Zrttitg~}UKIZlH8`^Z!TH%08h^@z8;5O&D{918o-IFqx<46soYzKIvyR-SQF29i zxrOp37jWL!BMXovxFa(p~EI2#^AO`T(Tj+sh%mo8WEO@0K>3;cK{zilprXcibp>;0yBP7kI)aA@#nR?qA-xPpDXu>T5Ra0({7Y;psq`${ zvTZacGO)ZxwC5S3JuTi9v_!iI3{OeEzywwyIOvm5wAcCJW4-CF;K1^nw&bY$+e$ze zf6+^Rn6k2VNz7Ort}`0KJTx$rGe)nQbH4Mj{Zm<)M4FaEm0G(H61)qY5s>`QV)+SMl+N!k<^vKslA;OsfL*2{C?FkxkwFu%=>gps7mg$3aMhnxq*`I`Qnx zY0NrIGD%N%Y%vqdy0CZb0p10@417u2Wve?rK#|P>(kw%XD+G#2F-K2oxxczNm0n(8V<(S%7Mj81z}iC$+Qx>*d-r7^@fo22VAh{-&M z%q8>87LqxC0ZF%#g)q5?WMz{@IV2a8yv6w>y?`uP>LE5%NSFm=8Cp(O6p^fAQbJ0J zo%~=WxpyTgE5DDdA{CY79tY8_Ci(WSHa4Nx4|!idgsLrQEk6CWaPr1a*P1_BXu+)) zaaHl}(fIM!Ng!GOIchsJ`5a=e*Jq--f8yIMH>>dJhVG_%&oWPm zM{B325P2li?rV(U(x&rh{MUP9H&N%7jqA~2cuwz(JRPg~G=Qgfg zT83_9?wLY|-Kfz$MM`EosJ?q`ya@gI7e#1#*9No~-9nk08>Xl7yl3Xj%%E8L_6z8# zPjf7Jf<-vp0FHpQtrtu4;e~yd8r|p+o?L0)Ub_c1c9xqHPHEmXUh1qyW$54$kYY}4_=eDoW1A{H+! zb!w6BT!i8);>Gdh@zVItXM}PTuZdU3tGd_Mwqj4cS7|t7{>aeD5>7k)pXv^fy(gF_}4;G+FyXY1W9-tMhrs5fq zeO^>hG*xj#X{)QkB^|Xh?E7H>iEg05&x@g*cj-}dv*Ph)qy0u2Uol@aaj043MM$A-T9y?4m| zpPkO3KY0=aV&8X(_6$yijt%X*!~74Je_vnE_a*qQT>KTm+>mS%On8_GDC~w1e%-4S zz>py+c8}MrI6|`{VRy6$uC0)LwiiDy;SqvIiI-uYlQjNF?;xTTyV^8JX~QP=NeRyz zk}{(VyCf)C6oXk8V%X(DZkRRq$mm<#q6xp7lp~GHXI53peRs($`=hKbx^KmIx-t*W?O9FQt5m*A8E83U`h7!Ui|sW2azwTM5buX5V_ z%5rb9V)yDH6bx(gOCPH_r_9vg9E#K9BeG;r%n*z0Aa3$|@A+U3rJjS+fw>ge3qD+% zOIea+tmr6(hoOu#+Z%Q#ymKv7U*qeQ)4;p%cG*3oo)&7W|q ztuLZpZIdnFp(~Io4{+tOz-Q=}Qn&eXeHm>O_&xe8k5Pd0w!UyVC^JQ8fvkQPeyLA; z*q`@Bx}4$i1c6JVu(oFex}0oVAGU?%gIXm=X}Df5krDR>zyJhgMG#Mm%3|=OFetgX z-%1C#bIBdenN&>ouwV6!zrmjGgDgBUyb13c3T1pddAMN^c2?WAB(_z(WZ}-T*|N{l zo2jOVlwbgrhh?uWan(nPUns#fvb2J$mWsF{i* zs(~|V8RZP{dAj-KU&`9zOPMVR^cv10YL@9ZqQ*gZk_rwk$PMSyQypXGsW#R=(9zM6HtO;Itxd2&hsbn_DOM&XCp-&z=H3qT!gQdCWY+ zJ?$F*KR#Ebap$sw+<04>?kadAU4_Nf7o7=&l-Fp59006KqFx@%w6+>G0Y2gf9>Pd+ z_$oC})bJFt9YA$=K-|uZyc*;?bDx?IUbo@0kf=Y?a%}6E`8Leq$FIrFHabJ&%~G>D z#ufzm$8&A-q-v*B2*+Hgd&M$rZ$vzy%~g2mV6L8{!=~ zd7f_Ze|Vd8O!H2RzpANO)nC79UEKz7{J(`kqk17Ig>>PlMZ{Xf!jSAz2wusy1Lr-b zq*mQyx@IVRJG4LTvTsQ(oJD$+%LEH;;k${d{ZTT4rBJ$nl#7FGaSy+5(UK(qm_^Z9 k&~0x3JXW}@F5mDaLx>g)E^!eHt;yWOW&}^y8F#1u8!je~nE(I) diff --git a/bin/basic_ultimate64.rom b/bin/basic_ultimate64.rom index 0d1f0ceff0912949bc158a79909bb1cf52c28b74..482ff3978570e8dde9fcd0250a7babe2bb528d23 100644 GIT binary patch delta 1864 zcmYjSYfKbZ6rKm`EDSIU1-liM>#KkWq4?-Z)q)A>w!Jon*7T*xKx?y@*0f3cLuj(Z zI7&=v*N!G=Lo$qeXLlAgON}uiucRs6*|v6KNSoHA9UxG&iJgK~)adriE+!_sbMC$8 zb#HR1mbuj3gDpL>oWDP4 zRGR`3;AV_h1ZM(Xr+P)SUe!~Qpiq5nMz6`i`U6Cbr?)kspNzV=L7MGcN6lnWPyrqI zl4i5i5%Jxq@$PMrT2xwLFSfK&CtGGZ%{w6$nF<)eH+#U3>OR?=^gNJ0mUHsnVD=5k zVqWbF`-b9Iy&|cUwvu(yHg&5)qqB@bnXHqa<25YKRnV-8HVol0RbheW?}Se*01?W) zxhqO{p3%n4aw8a89rJhj^?7NdJ}GTFS`myXDYQ8%|DB8EU-{Fkz)wO%tff-u=T!WG zk!O3XogtUH7+)XirkEM*3d_6r)y!m6Zs(WQ2Zuh6J|hjMNTvtF#T$R)@ouoR_ooxeC(F(49%oTmb(V?(FQ$83~5| z3@BxA+hV_(Vl~f4P3|o4*Kp*uz%xD7?9Jyme{ylqrA>mBM=M>&8@em-I*W^#!i#MLo zoXrUh|DlE5mnk}1I7QLZZjeh$0pp-HLpX!Bvyvc_)F}{_2i!HQ4r*cE7M@hXpJ|RI zP#EQG7H`*NA-g!ZXTtQ1{t~ykWzKJ}>Bmhx<+P#V? zwd5`C<@NoM4{KOGrKA!TW#?a(CZHea=mv z02He&qmJ|(%sMn#|mlVOOuht&Ut9>M+Nj3X(ptPlX&8m za>KmFP4k2|uA3|#*9U_X{oDMcIW?0Q%{6B=J_$K_DmgemSs~cGLybpJgrmCBkzSj0 z0z#yKfE)lrvAj{E?Wk8pzi%h|UAi~#jR%P|u} zLN6Ljq2Nd=#9~*kqrWS54w|*beES^jkS2UT_9O}nx5pJ{ag`fXYs{$I$ z*iopFopuqrlrjYv6KT_sr3Bs|6T!Ypb=G7%J#sBIW8Mb)I!|f+iU@ax`^ZaNJJ!ys zBxHXJ*U8NI;&DH$18G}-hgKftw5^ok0V8HhQF426;H6VX@?dEd3y)oiCB?#$%7q(v$s?@7fl$>)Y2gBLm| z&O;hta6vR{EL=N|a1V*Q`s^YV!Q(*sU_y{Me9|}G3}`>_s&Iu&MG*@lqA3zClUVUQzxfryOSg WSNxLv&xhg7a*WIkI}@|aQ};j0p+3(5 delta 3178 zcmb^ze{d63`enCi(xz9V@7H+G{p5BlCbh+3^^Ek6Ffcx>)xYb~EHvf|z^ za7*>ODE?~iG?1+S61fjfKZUq&JBm>I-|>~*ms{}h&cW^u?{?HxwFON#f7F3my!dVu ztU%X3=-54j)@&{M?V4@q%dd8IqxX;fu0kBxTWrO%9`yR`;M%QcQCHyG3US}I85Ee? z^N?e92GIwK>H=L!T-*IIiodZpc^M6C-MAhdg6H_oi6@e6pOtJ!$tSPkWJ5V;d1vF= z@&+_l^ymyahhq2c)GrBhvQMyHPC2DJEeKoH8s$R8qk%WV^H<0 zIZImWvFIoNuzcDJ%%ApxN%-&p@+Ntdyo3h3eGt#&p?);I5Vc=H6|(nAWuoR_MrK(daQ?;p`Pl}Bw)s|{awG6Iz^kQ#^Pw6~i`NTKa)wxAHG>uBOtI1~c zilf4@*YR=526WIdu&WHsJ%yf5qU2@R9{lxpXzTRl+A=SSkCmb6I>{pL`@L(cK-Lr&m!DLAnN z_?v;hFkqjeYOdnQ$ldPe>LZ$hK`A56%fvk@6W{M5o~Cbfyoc=n2JvvRD^z8<)x)Hj zznj?k7CaOqt@^e!3^-fyGqGqI-)h^F1#E45fK6%@88DD8W%zTW7M<;}1-ch3I!*+8cmr=DMn2DP3K-%hVp9IBvfN97 zaise^cuc);apFv#Ivp@gPN78M+AJ zN1()H)Z&sU_yNFzlMNzdzi#q0RljX=9dV}5iG2J)K*r#@J2atQa?4iOy2A1Z-zbYh zqp_Sh8xS5e-sv@oX_{Cg=wGIo6NTX;&M9*u7bIto--HBI4rmy5;ohM3aQ6o%jyPkD zX>OOsZrf7;yj*(_Z;8qWv_eiWaJxPVv3Lu*0EDkGf@dY=c5tvhLOlH2WWSexCj-)) z%*MdCt}fpn{$Uh1;S2hU~3wz8iC-oTxca#od~1lT;#)}--=;N)>swI=O#vF1@UEedDUS%}4aMG)&`;}FVo;eT7icl^ zCN05AWiYIZnAAlVi9yjNSeaJIsYyH@(y-$p&LI1ZCy_44{3_DLL3@S`5W}Gi2i%%L zp49R@ru_WISuYb24{MRv2{&hVu;&{^~joAR0R1Te89& z%Aomc*Vk0+T8100R-=1Z7TD}N1u^TkJ6;JNWpsU$mKitK9PaDu%RTM&{nag2Ku<4n zN?A5Y?x!Q+qv$%#uCVa8tfkB&VIfcdpzvf#CG$*7c%x)-)?dO13B{&G#aN9=2nswp zujD5zQ=LA&bPM-URI4klWmqWAD%;sl(%r=8P@1DH#K3DIHo)VN8GgT(1RmZHFu-NN zFk&yNmk%2t|L`BfQ5N?^iQ)Ig1dBf$wz{t!p{Q3y)k8!^k5m~@F``{IJya?E3*7~k8tQuhd z2u#29vCj7g=u8UfN#tp4DvN(I20ZW^{}*K+#eCTbdR$@)*oM4A_Qs7iu&HtusltgFFt$gj(IwR)~Qc z2gfACiQO-6o3vbkJ^YKTgls2v@7wnB?u&hv%f$WgPTo!2Dg+I`Jr?gFJ(eU_6X}1a zqL8#YNt=@xn=Tk^PzGUqez<>~Jr6X4NstmS-i0$IcA=qUdHJFUF#&~X)D1nly6J+6 zuO>C$Aif5~rW+M}bvR!YUG+mfFg;k4=F~WvE8bNFA1{!C4y|$ zN(;j8GA=B|Vl+q&4!Dpv)|KyNG+Z7h*5@cmhQ)%cm7s$U4mfws=p*lTm&rUQvH8-j zLBpkQ3>siI=fd8FFnn z|6=W{JBps&w&f|Zebdv=6+g3ab6Md|!;;eHm#VjxEYH%KUU+=jitLrU))%Zp3Px7O z$VwIc#>#Q3cv+R8lvRmJdDd)M9XCf#Vw2?*c`lnOr_FmrR%_(>KrE0KE|SwTsDMvo`!NisB9iY#%g~BBKHc@ z&{OyE#J7U$@Y&+VvO-fSDp|e*`PW=8MCCk)-?O{Ae&AbwE3*{&UU`6hPdrB0_lq_@_5>PFdpUq!uS6x40r~MsRM@yN zyd2&9#d0+E(pIz|g;3h|;<3PD^ZDe-N#tAo;)m#aw=z-}TTH2zv&FCw2)F#s$}D)` zrh$@5RE_>i9St@p{_n{ukR<4wL)JAtYRL z6#01M8%2#}W=N;+^?Kw_K~GJfrDI`j7CMJc`NG&vmJ(CjKc&$`WxCB-`|ulrGEspMOOeyLxo->>h@+={C8M_*ck#w*Z| zeaIICvidh6w9_A4xdeHBy#)Dl)Up!(IXmKy8P6D-H5|?k%`hbBw|CXe6Lux%F04C; ztf@zS&R7*kY8Y$ck)JU~>KVL!oNO8vHmUTBW`*i_hC5_9VTiB57lv_F2)`1>`$JlC zdq}XT9x*x4C%RA_`h=Sybbkd-caIJk#A8yN=a|OGzrktn-C@r$^6@aWh1-Y0oGoCE z#i|gz@#+wkgVs3F_BGz-jK$3XlIo$p+(T649_nU?v{o5hu<_l}eL%#aAqarKdB{W~ z6HmI7-W7Pe-G(sk!?GZg6y&XD3w4OfBNed5h#7XnoKrpJ{y{ZdN_ zkfa;@E%M}u>zI^}wIi+~De+88FTg5Qv@D$_anfCoovCdx1-j}3wJp6}^}V$nZt0%q zmL1pkf@ae#>1kK0RM_N}=Gpoq<~#dgj@ZY$@wE}q0LJF-=<_b9?P}?*t?%t>3DnjH zx;px#d(<|y)9I#`Zb)%pO-XV;HRw2LmQk~(%FOKffb@TAw3?DWSv)GmLh(SeoAtX= zq&RyO|3~0lM}b7sWU|DHZp|Jo_-?#A?cS9x#e1TmxauXf=*}CV@&3QTjnUUwlHUNl@zbhBxl{cH@F>c`(3iP`~5 zn46$yel#LHmyo5nBm6iaJ0mz^RxN6LGb8h@>NkFQ{6xdaU*Xq$xKYNVGWqGKkdchD z@%~Y>l05JyczGMX;d4SjATKKyXrf%Z;bl0ibqmo>)E$WVy6_7XGfgl zRmOn#j~O)_f8oIUHNWG?KLQm8EH$TjYbhuG*{k5h>+pa$d-&_%*skDvU|d?)*~8|E z*QE@|p3U9T%U|14Ro~kZs5{6wYMA-}=v^lld>|FC+1&NLj)Qa%@z?FCV8AY{P^q&> zu7|&PptYtgvJTadA-E&^T%Hs|KP8!f%CywiFx> z3ib`;JEOwwlxIxjVgQj12dQv3sB)q$&aSqQ3*iLxa+SW4W4;LjR8TGd# zQUqh|i4c^>FJ5dYW5l+G-Hh1U@Li_szzOk!H%@G$LBoXyzZZ(cF1F%t&{75c_|f}V z9V7=M3!bDflkhbR=rRp4Ck)^%k$S_wmq}Z|cn0SN$echFu~P0wP$Qd->y`kshK49^ zi4ET5=^XV1h3cd%ZS9yx0@r`=iJjh$q0TO~^dx@Y2i2x1(aXEU5BYA`lfs{q=Fh7g z({KQ&b~Wt?+)cHJa!i;^$~Eyq&6NXJAp;Pz*rxjzEdS#m-Wr6}MV8eUgezZUSpY`r zAS`c?%93fh27`7klJW?RrNH$2?i9TJ{-#zh!(YLl=dR)(2B!xGgLoM=W&&a@CH@o? z%{smJZ}`{LJk;}gP;8)OR^q>e#FNw1Z9gT@E<~ zaz(U5)DWgqL-R~RP8J6F22Hc^%puNrhJ5CSv}*(NpjyB^ppUTsp;6&5yTAm_)sO_| zRcb*Wa<)+mCpF~QI9Fk_G@TZ$rCc*acLiIRNd@2g;Q{m5DyL$*w1@Sc({M3uMXD7 zFRi^VjLp@bZJ!;lcm}d@?!Ci|S9$F)gC{4%b6&LtwH{}%Fwxa<4lo9OQDqt&b&M{q z*{Iu)zIUSe(%$>t*-f4Q_!;9>oqCn=baIxsz0mF*6T*$eeCF1Kz|LB@<)0IFR9DA1 z6nAt=mqJom<3IuOlL)t;I%b+vLjSCvq$;yrF`&XwmG~JI%7IvTWtNT_ZJf2wbYa38 z@7M{^VxU;Zb5Tm;*b$|$V|$d+I<`fr97jo%%5xM)DdxN#7M9T?FkWrXF~*zK^9JM1 zu$^mHLY;3-G#m%8JlD;BWCg`j0@KYxnOsT2q1oy4%O?$v!%Pk%%`(_y>JBqTBYAGp zNXjQ$6nhma4g5A66&9pts4VlXT245h@by{NsXA0;tvYgm;e@x-H}1&}MG+HjcX02r z1+2+XyKFWIa1$>Mz>N$pXdtn|nQnk9U_|)9xYuBrA0g+|M)Zu)TUR&xF-$RPc^f@V zMVp2*MEdEokWiG7i8aHe`xpyM1eBWKDhv*dQaxYkjWO=iD2-%uSU5AsuuUuDu{hXb zdDuWR!_L>*!k^q9}C_fc_hg+tmXTz^-s&_Ul6ei_e)3+3B>Ty?L!`$?ihV+R=AtDp_{eAD`?Sh^*~)#(m1LKn Vn2fDokwj6=PVSuR%&mv zx0jPCgq_hTD4pj?4Jr#u=i6mQ;cz%CXD6o|B@06MQn-MRjmo=}CFtO&T&ZNYbqvW! zrH1Z#Nr=SjpsQ_b=!geh@rI6}plhh%R7e>gx!^;tA+T({psbK*D$80!%1^w*hWq|u z*dv`2Lcj%BfZz?CI;YNV2zCrLxQ2oq@dj5sc*sMgk z&(6PI=VV_$fj8D(w|k~vmTo8+%?=hU2P`o;Ps#Mv3I7C1{tG}R33C;T6yjemg?E>X zCSNblQOqN$P-K^qBZbOuP`weGd_XbxPvIHLv}9sZI#J0$%fs-78FF#Jpzlf`OYU)| zTWj$~@nq(b67jk>)U(=2UmpT0!PGn4b&;`f_@Pl>UCTuVm59jvMp~7)(~Q`Iqv9d+ zn;<-#Rbl;QD!f#?o4CGF^()`%p{cSZ0bM;PtaP*@{SuIR%A ziX`x#BjPK0i+&5WmSt&TE?fT%138#;iI$SR0zx=)Xa}ouU+iF!~+i=Vtryo-uV=Yya4LteSq{O?IT8xHGo|ICL>0p2%Oq z-i(NM@(Wh6-}soOCf1*J$;!!TO1dW#3}jZx_M|m8u}O(jIlOj^noN^TV8T)p^OOmd zKrOyH+e)1_&aSqdj(E)ebr3BAWbwb0LcIUQ6hi*BDOBpON})3UniMMcuTCQIR|Q4X z=PLz|<-av%^Y38GSmi#O&(ySowcGKQF*|;1?C=)eoL1{*PIam?J;%^NHh8L&SJKLX zW^Wu1+@v&{Ydnh_X>P{V>sjnbD zmy!C=rg5nk!*IaTOBF9x{;&)>Uk*N-@J%l#t-anpo*)#*(HI@?#UxQN`Q|9se1+vi zY%a1@EgMIZnXm^h9fuqhAdsh)&~qsrtWdS;EU->*OR9ytsrg>V-Q;dK4z(MMilxPi zrb#VupryK#gH9!WJEP>+x$1}lq5L8&^{Zd`-(=++WieV1Mt8<(?-~+h>8vn7J4LXe zj5pfStzdl+8mi)E?Cl*g%2jz{Z|8kE1a_l=3D}8uj*Gvaxu_PpYDT;f30mOMuFb5R zrk2U9x}a+Vg$rSY_R<`*Mhoz;hRXDS1r~)CzTMu|NbGHRBxY|*k_18w1gyt?@cDJp z=OyrYL1xtdfDiT3_g*C}P}@h{&ea3m)a^bVzor_EyavsSLxV?$bWbi^!ugiz1IjIw zA4lJ5$fJYC11-e{MuzgXeT&VVZ@~K-3_E+O=?_@Gf-Uw^!Aozh8m_&D5d#1lpcJjS2KlVtqAS2mG!o-pqY) zMT)V<&15JA&A)<8-(M17V%e7MD@D}rc@@*OYJ%F=& z9yy*qDbD9BpvocKY#J^)nZS=vLd`CU%$|C*7CJ6-Thms@T-;yg}DRo1uHTn0jL~_!rV#G{9 zF@;t9FHJTD;QGKn$!+R5%aZ(j1KbMuJiLZLDpgZC1-WHiN^>npjy> zoKZKizM6Hz`gIO(oPhbEiUfW+fj_>BKfQrx-Nm!-V$UR=tK%{qf3D$AHM~87KhyDk z9lt$^&uKWUVM)VlH2i>$n{~Wf7ki2e=L$OhlU`lQRnO@`Iw@-`!9Rp-t1Q4I+lEg$@V8dIU!HCamSc6}CJIrmeBVZ!8tk!Z1!tYQn zEJR~8Ko0f0kQnXC6DbXo%kZ_?O7cmo1zF312OsKp?w;XC;&zwGJUhOzb@zaw^_v3* zkY-$1TmbTGKz>d`UcV&7yY$m~hwNl&zihzPAJ%4ihw_vQl;?GZFV7uOu;u*gBZvhI zJQkGT7r%yG%jdD{Fx$%KtJa6tKr$cOTb*HgzGiO}h^^lXV%B^M1rD-nI^|~`7(stb zuzc}%rDfT}73r_0yR9<$9{)uq+nHeyToDoe+kYwfBKMcTOb>ne5=#E3j<4@1d}iC0 zC&~6rPd!`o^v2C41v?FkcRja6y|s8*rq=ZQilxi5R_~Bh3R~zO-PWl$I`KU}@1;G9~q5>Cwle zB}gkNACYt@OIo^2TCiMNA+40MrLV4%a#l%?ul}0!gp|8Rnx7|`RBNTo>`x0z(C;hF zzpq63DQF`;*KRp8{)3Hl@4OUTdIzsteg%2zN`1hxc>ozJePxK;D@a98-p3Q)4y?oH zit0-WOuJC=vK`2`=2`(-hu5OtEJ0Hr7JS=}HtbBjwBb24@b{NWQ2UwpmspM+NKe6I z<>=RA^&5AZK0?I}_m)_G^qe0xjPKo}AM+#W`PA%&VlQ4<(t|v29q_XmG9$@d|j}iL4!i|qTj>c18_MNkd#p&P$ghQ?mn ziVmP4O5I*G=3ivKkTf}oysKaQ2z~!%ddeb;DaCTG2m%3jOYf}Aga>ZuFD^%w*taVC zMg7aD_}FSX9F!bgasRP=^f;RMF$Pm7#_6!tGfwxv=-yHg?kxqEaMdy7Ws!Fj)t8td zo!&QUkuMoNIf0gpg|wOIJUZ-T;7=zYC(B zzQD@G$n)F9$d|2_l<>#c5qsQt*4U_Fa8_^zApxJgvt};0J1J*D&3R-^Ir?+TsyJFj zS>uoXj5=CN;qBvO(-5~wrC*p3tYInUu;HX3whUh!!WBXMN(dhaYRT?tj!sX8~r53BinKh$|Uz-7d@!8N??MH?Go<8L>wFh2iO~jO|obFDVI`Qj<@@q zN&F3bRx+pJJzlLGcP=vnk>0=z$luT~Ww_1D-)M9pm}=khxZF>M z%9SD%G`NMiw!X0Xjy{m#ds#QWIszPk*xc>C;{58)rk?8Bp3WwJb*;a%y;ry=>z4I& zxMfY(g&5GLBsrfNbc~Q-)aBRG-H=LPwe>aMLcsjiu)U)07Q*$M zE#_s#RgR9uly-z$75ge6jj?*&#fWt6V%MMzq&al>94F4BV!SL7M0e*I~*TAq{!FI#Cu&$$<&gHKO>5x5}yQzo0 zx}~DFr^#P)h;md>wSM5cMlO1R%3rm)YkM4r^1LDtU1nX9Qs*K#&1noSwCj>t3!qY58p89Ct-IAw;Oz z1BT0w&(YzdL1#hp9@yC z>PjfSrEU+!H`jfS>O6RozbMA=Ewa;a;lb|)!@l#)_?vR60zUlceXI_UL*alYSGfVFtp8vc_+TKvYdILA+B`y&%8`F?n6WYIBQ0?e$zL3wWRbz;(Vj(P)J zWn!kbddwq$=?}bohxjqn*`*eq!0&mX+VYg>VO{)3Y!~cF?k|b+=2nks7#OH_wcHW7 zOXecVF>W$3$Ha0~mk(Zn41mvki|$_#{>K5lH2~3t!|Dydl`k9?3?p>_!W)ojNpiUc z0(K^x@-U1A|MYu!3f?|nL$gS+m+|MZEBHr&>4kv+UMedy0kBpE{v6=VI=%Qe{99Q) z)bm<^uanEH#GeHDQ`69GA2eB=UCEweU?4-r-@NFMsLG2gC6zd=0TG`otQ6ngFAx*%TZn$HgwOwxVa zh15k`VJN&bGf4$MV~uK!s<^vb5>#FExI9k5L|iNwjH5qqHSXd5oxVC)SG2CZ&yCH| zpKF^Ht9Tl+asJ&Sl&HLVgu;^({CQDrLCq&9%uRH*pNAO(UsM?eM-8QmX*B9Kr0tt% zY~6QXoYm0rkDpPZ>h!CWr-QM??1Of1pWv>?=TSE&I67g$mVZvzQB4iyP~6ceT?#>E zjR6M8PdwayYN%;U3H`HvQf8UuiUJl&W{I6)kue~1uO#SXrS%E>O&2Guv5uYKEe42o zJR5;DjvWyQJGMt4tz%mR%61e-pj<~$1fnk3A+YprjuN%q$0;$h`%Owrx1DcOLY;3; z)SZA~dA^IjWd+959MwfbnOuq7;aO?(N+%7DBUCmeBpB>bHAg6;kvuzTB&Cy0ihT-| z2ENTkx%p}7D$6{pmf10NKxDmxWSlLDKCdMP9BgW8vcGz2vj;{aWSzEam=XO0wHWa;Hd2&~nF$ N7=(Tj+9PH9{te*+#;5=Q delta 3025 zcmY*b0Zn2fDokwj6=PVSuR%&mv zx0jPCgq_hTD4pj?4Jr#u=i6mQ;cz%CXD6o|B@06MQn-MRjmo=}CFtO&T&ZNYbqvW! zrH1Z#Nr=SjpsQ_b=!geh@rI6}plhh%R7e>gx!^;tA+T({psbK*D$80!%1^w*hWq|u z*dv`2Lcj%BfZz?CI;YNV2zCrLxQ2oq@dj5sc*sMgk z&(6PI=VV_$fj8D(w|k~vmTo8+%?=hU2P`o;Ps#Mv3I7C1{tG}R33C;T6yjemg?E>X zCSNblQOqN$P-K^qBZbOuP`weGd_XbxPvIHLv}9sZI#J0$%fs-78FF#Jpzlf`OYU)| zTWj$~@nq(b67jk>)U(=2UmpT0!PGn4b&;`f_@Pl>UCTuVm59jvMp~7)(~Q`Iqv9d+ zn;<-#Rbl;QD!f#?o4CGF^()`%p{cSZ0bM;PtaP*@{SuIR%A ziX`x#BjPK0i+&5WmSt&TE?fT%138#;iI$SR0zx=)Xa}ouU+iF!~+i=Vtryo-uV=Yya4LteSq{O?IT8xHGo|ICL>0p2%Oq z-i(NM@(Wh6-}soOCf1*J$;!!TO1dW#3}jZx_M|m8u}O(jIlOj^noN^TV8T)p^OOmd zKrOyH+e)1_&aSqdj(E)ebr3BAWbwb0LcIUQ6hi*BDOBpON})3UniMMcuTCQIR|Q4X z=PLz|<-av%^Y38GSmi#O&(ySowcGKQF*|;1?C=)eoL1{*PIam?J;%^NHh8L&SJKLX zW^Wu1+@v&{Ydnh_X>P{V>sjnbD zmy!C=rg5nk!*IaTOBF9x{;&)>Uk*N-@J%l#t-anpo*)#*(HI@?#UxQN`Q|9se1+vi zY%a1@EgMIZnXm^h9fuqhAdsh)&~qsrtWdS;EU->*OR9ytsrg>V-Q;dK4z(MMilxPi zrb#VupryK#gH9!WJEP>+x$1}lq5L8&^{Zd`-(=++WieV1Mt8<(?-~+h>8vn7J4LXe zj5pfStzdl+8mi)E?Cl*g%2jz{Z|8kE1a_l=3D}8uj*Gvaxu_PpYDT;f30mOMuFb5R zrk2U9x}a+Vg$rSY_R<`*Mhoz;hRXDS1r~)CzTMu|NbGHRBxY|*k_18w1gyt?@cDJp z=OyrYL1xtdfDiT3_g*C}P}@h{&ea3m)a^bVzor_EyavsSLxV?$bWbi^!ugiz1IjIw zA4lJ5$fJYC11-e{MuzgXeT&VVZ@~K-3_E+O=?_@Gf-Uw^!Aozh8m_&D5d#1lpcJjS2KlVtqAS2mG!o-pqY) zMT)V<&15JA&A)<8-(M17V%e7MD@D}rc@@*OYJ%F=& z9yy*qDbD9BpvocKY#J^)nZS=vLd`CU%$|C*7CJ6-Thms@T-;yg}DRo1uHTn0jL~_!rV#G{9 zF@;t9FHJTD;QGKn$!+R5%aZ(j1KbMuJiLZLDpgZC1-WHiN^>npjy> zoKZKizM6Hz`gIO(oPhbEiUfW+fj_>BKfQrx-Nm!-V$UR=tK%{qf3D$AHM~87KhyDk z9lt$^&uKWUVM)VlH2i>$n{~Wf7ki2e=L$OhlU`lQRnO3^rM- zfAo(s%)NV`z0cnJ?7h$LoT<`R=}jbk(3(LWz1P$>5btEH@to&h_!|{H23-~JF(#@; zb*5%<6qwN?2D=)6EZaB0!`O@;y=TWjSr-8%7Pw?@GTtZRtfg{4@G2Fc+87xKos3cQSl%jd-UTqT)hu^?+D=-|Tx&OI~w$h*U3GS5zI zzOrY~aOFFL2AIvcuy+B>Ujy^!G!+cUQld*gZFksCmJUz{wt)BB94Qer%BaAIZt zh=Q*a-xxtWa1gPigt){t{93VqUxzne6$@4CBV#bL5bwY0jK~W$`(j|)`h76XT4-S) zKz>aZeHMU|6_(tqU;Q**ef#l<{AW{AL}BiGUsd{p^`nn+ud3inKdsUCS9Sg^oau2a z{}yxq#M(D^7C*mz>$7CXrp+&uJhyR6S+o9i-V!wR`=aj#(1u;0?yd^k9kQM=u6Y)A+u<`mq3#UrNtyD)r%&WxdGr z&Ou)g9p6>F1-%L1^Lx5}=v#j$Yd7+}_6Yl)eu}Uk7H@p&X*8bxY5=`iiApO2@`_1R z)VMLc4Bh_UWoYb`ZRj8hq4XUkV}V8Hiz$(k1ErOy8v9q}zN~*0l^$QsMixa^S2}RK5Iv11evHA@$#FK~^{mtVcebw_Cij&? zNVw)W^6|(wiW-eHe`PTm zuRuTXAzu*4>R*M>E`M<4V&wVdV&uMJZEgya5yJ4!;qlg-c>hO*prgC zpzZ>)rXBkq#;Q10!&noK{fs$Q&)^;7WYe&)Nu^(y6sqGH?ug-(A-)1%8pc&2{8|_v z3~9;TA;F@0!sI}o=|XkrGj4{^{TVpj13F|7Pe^f|6B;A`7N^1Yhdn3Ar^D11ZXX77 zwtzVnt3vR`t3y~0TH{39w|JW~7B>e-nuq#w4^feOsGA+qT4iv-#&=5(0TG9WAOQaM z5fhC}Jnd3?m*X9NXNq_mpOek$c&|@O*PYMJP^2$7LyEUGTm^3TiMN|w2vF@mJg&s) zms(1IB;DfgkY`3*C!_+b9dQ*)iRW5+0amG^Wyv&&lkbDgbamP}|f_r<+>3CB=a?CCU5TpyQ+@qh?=~nc4Rd>HpklH6?$xXjF=Y;(=y2 z>vyF}arP?y_rST11Bs@|6p0nxntfXE-FSc6y(>eC_e4W+)k|v8oj*e5k=R^kr1;Jm zdX6*;?6~>Ij-`rej6-C@R2!_)^r?M2tj%L;^l@iMr>=?%ZRNF-)FiGof0p3&QV`bs7}t-){c23aQ!=<*y;Tg>g-ZW&)^SzP;H75y}V2OnD2%?Df}^c z-rU+T4F`Z~SJRHb-BgPx$Arn`JQFX}Tsw3fG5|4)ZMwh1@;?pYZ9!OFWLbSdxbj7o z1z@BO!tw^GEQOY9Flgr@DUZ-t3QWK6Pr=*oZ)){2{5AY#?mGTaaC%@ch?i1hCLq>Q z;txU5tkZk{5C4*yhkD)&iVd{PO8lpgczT+;>xU+5uq*k~8~`$8jP}DS=m(d=o9kk{ z%OIyfE{}GI8p3pHXr4*P$-*GtplLRqJHi>ykuUs^c5PrTR13IA^bz(yHYyxt=bON} z8j|3=PA%v|&Ngb{w1%7*=PGQLrn91TH`ff&9RVf#bniju;k$m$f;ujF)2zRNYh_o* zC5@!Whcw+ECdol6jjyog)hH~e{+jif8ikhgT=Oc4JLtJCDM?RI!-;3uC-Jecpq`CQ zREyb`xcR#+$bnKZh41@jBipi`NJ|&al_0 zU}y0^hCyam6S(&$=W|WhY}cWOv;o?(@Qe+Jf)r!VkcR9F=`Eg(G1+Cf&;yb{vdR4^ zOJXfMMcX-dl7a@nEBTwx8FQ$=#%=3wa?``p8(eK=1NS}XM1Ex)yR?@QW$i;@Y>xhX`>c4ybC8V-9~@=8${R-+JUJm=@Tx7S^(2FZiLQ9HOfDlO8SF82M;W7$ zyfA4b<&!On{R))^ew&R7^D{D4mU&h!CtOVUc9M0f4pmvJjvZn+;oXdl`*K22#Dv=& z+`DW6YYNmZhfN0D#ESxOBZCVXNUU(C8{i5U5k4~RH(2IH$l0|KJ!ACN)y;kiQ;b^P zMo&}Grr`{ce)=LL6lZ2(&G7C6j0GkFN=|a{yK0Loz-r<0CSzmUkaO7BBg>Ox~R$g;OMbip-xP-v|(Wh>#Gu z5h7PZmp?SI+kTKmLH=p#T5? delta 3025 zcmY*b0Zn2fDokwj6=PVSuR%&mv zx0jPCgq_hTD4pj?4Jr#u=i6mQ;cz%CXD6o|B@06MQn-MRjmo=}CFtO&T&ZNYbqvW! zrH1Z#Nr=SjpsQ_b=!geh@rI6}plhh%R7e>gx!^;tA+T({psbK*D$80!%1^w*hWq|u z*dv`2Lcj%BfZz?CI;YNV2zCrLxQ2oq@dj5sc*sMgk z&(6PI=VV_$fj8D(w|k~vmTo8+%?=hU2P`o;Ps#Mv3I7C1{tG}R33C;T6yjemg?E>X zCSNblQOqN$P-K^qBZbOuP`weGd_XbxPvIHLv}9sZI#J0$%fs-78FF#Jpzlf`OYU)| zTWj$~@nq(b67jk>)U(=2UmpT0!PGn4b&;`f_@Pl>UCTuVm59jvMp~7)(~Q`Iqv9d+ zn;<-#Rbl;QD!f#?o4CGF^()`%p{cSZ0bM;PtaP*@{SuIR%A ziX`x#BjPK0i+&5WmSt&TE?fT%138#;iI$SR0zx=)Xa}ouU+iF!~+i=Vtryo-uV=Yya4LteSq{O?IT8xHGo|ICL>0p2%Oq z-i(NM@(Wh6-}soOCf1*J$;!!TO1dW#3}jZx_M|m8u}O(jIlOj^noN^TV8T)p^OOmd zKrOyH+e)1_&aSqdj(E)ebr3BAWbwb0LcIUQ6hi*BDOBpON})3UniMMcuTCQIR|Q4X z=PLz|<-av%^Y38GSmi#O&(ySowcGKQF*|;1?C=)eoL1{*PIam?J;%^NHh8L&SJKLX zW^Wu1+@v&{Ydnh_X>P{V>sjnbD zmy!C=rg5nk!*IaTOBF9x{;&)>Uk*N-@J%l#t-anpo*)#*(HI@?#UxQN`Q|9se1+vi zY%a1@EgMIZnXm^h9fuqhAdsh)&~qsrtWdS;EU->*OR9ytsrg>V-Q;dK4z(MMilxPi zrb#VupryK#gH9!WJEP>+x$1}lq5L8&^{Zd`-(=++WieV1Mt8<(?-~+h>8vn7J4LXe zj5pfStzdl+8mi)E?Cl*g%2jz{Z|8kE1a_l=3D}8uj*Gvaxu_PpYDT;f30mOMuFb5R zrk2U9x}a+Vg$rSY_R<`*Mhoz;hRXDS1r~)CzTMu|NbGHRBxY|*k_18w1gyt?@cDJp z=OyrYL1xtdfDiT3_g*C}P}@h{&ea3m)a^bVzor_EyavsSLxV?$bWbi^!ugiz1IjIw zA4lJ5$fJYC11-e{MuzgXeT&VVZ@~K-3_E+O=?_@Gf-Uw^!Aozh8m_&D5d#1lpcJjS2KlVtqAS2mG!o-pqY) zMT)V<&15JA&A)<8-(M17V%e7MD@D}rc@@*OYJ%F=& z9yy*qDbD9BpvocKY#J^)nZS=vLd`CU%$|C*7CJ6-Thms@T-;yg}DRo1uHTn0jL~_!rV#G{9 zF@;t9FHJTD;QGKn$!+R5%aZ(j1KbMuJiLZLDpgZC1-WHiN^>npjy> zoKZKizM6Hz`gIO(oPhbEiUfW+fj_>BKfQrx-Nm!-V$UR=tK%{qf3D$AHM~87KhyDk z9lt$^&uKWUVM)VlH2i>$n{~Wf7ki2e=L$OhlU`lQRnO +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) || defined(_WIN32) + #define DIR_SEPARATOR "\\" +#else + #define DIR_SEPARATOR "/" +#endif + +const std::string ASM_CMD = "java -jar assembler/KickAss.jar "; +const std::string LAB_OUT_START = "__routine_START_"; +const std::string LAB_OUT_END = "__routine_END_"; +const std::string LAB_IN_START = ".label __routine_START_"; +const std::string LAB_IN_END = ".label __routine_END_"; + +const std::string BANNER_LINE = "//-------------------------------------------------------------------------------------------"; + +// +// Command line settings +// + +std::string CMD_outFile = "OUT.BIN"; +std::string CMD_tmpDir = "./out"; +std::string CMD_segName = "MAIN"; +std::string CMD_segInfo = "(unnamed)"; +int CMD_loAddress = 0xC000; +int CMD_hiAddress = 0xCFFF; + +std::list CMD_dirList; + +// +// Common helper functions +// + +void bailOut() +{ + exit(-1); +} + +void bailOut(const std::string &message) +{ + std::cout << std::endl << "FATAL: " << message << std::endl << std::endl; + exit(-1); +} + +void printUsage() +{ + std::cout << std::endl << + "usage: build_segment [-o ] [-d ] [-t ]" << std::endl << + " [-l ] [-h ]" << std::endl << + " [-s ] [-i ] " << + std::endl << std::endl; +} + +void printBannerLineTop() +{ + std::cout << std::endl << std::endl << std::endl << BANNER_LINE << std::endl; +} + +void printBannerLineBottom() +{ + std::cout << BANNER_LINE << std::endl << std::endl; +} + +void printBannerCollectAnalyse() +{ + printBannerLineTop(); + std::cout << "// Segment '" << CMD_segInfo << "' - collecting and analysing routines" << std::endl; + printBannerLineBottom(); +} + +void printBannerBinCompile() +{ + printBannerLineTop(); + std::cout << "// Segment '" << CMD_segInfo << "' - binning and compiling the assembly" << std::endl; + printBannerLineBottom(); +} + +// +// Class definitions +// + +class SourceFile +{ +public: + SourceFile(const std::string &fileName, const std::string &dirName); + + std::string fileName; + std::string dirName; + + bool floating; + std::vector content; + + std::string label; + int startAddr; // for fixed (non-floating) routines only + int codeLength; // for both fixed and floating routines + + int testAddrStart; // start address during test run + int testAddrEnd; // end address during test run +}; + +class BinningProblem +{ +public: + + BinningProblem() {}; + BinningProblem(int loAddress, int hiAddress); + + bool isSolved() const; + + void addToProblem(SourceFile *routine); + void fillGap(int gapAddress, const std::list &routines); + void performObviousSteps(); + void removeUselessGaps(); + void sortFloatingRoutinesBySize(); + + std::map fixedRoutines; // routines with location already fixed + std::map gaps; // gaps by address + std::vector floatingRoutines; // routines not allocated to any address yet; always keep them sorted! +}; + +class Solver +{ +public: + Solver(BinningProblem &problem) : problem(problem) {} + + void run(); + + int selectGapToFill(); + void findPartialSolution(int gapSize, std::list &partialSolution); + +private: + + BinningProblem &problem; +}; + +// +// Global variables +// + +std::list GLOBAL_sourceFiles; +std::list GLOBAL_sourceFiles_noCode; +size_t GLOBAL_maxFileNameLen = 0; +size_t GLOBAL_totalRoutinesSize = 0; +BinningProblem GLOBAL_binningProblem; + +// +// Top-level functions +// + +void parseCommandLine(int argc, char **argv) +{ + int opt; + + // Retrieve command line options + + while ((opt = getopt(argc, argv, "o:d:t:l:h:s:i:")) != -1) + { + switch(opt) + { + case 'o': CMD_outFile = optarg; break; + case 't': CMD_tmpDir = optarg; break; + case 's': CMD_segName = optarg; break; + case 'i': CMD_segInfo = optarg; break; + case 'l': CMD_loAddress = strtol(optarg, nullptr ,16); break; + case 'h': CMD_hiAddress = strtol(optarg, nullptr ,16); break; + default: printUsage(); bailOut(); + } + } + + // Retrieve directory list + + for (int idx = optind; idx < argc; idx++) + { + CMD_dirList.push_back(argv[idx]); + } + + if (CMD_dirList.empty()) { printUsage(); bailOut("empty directory list"); } +} + +void readSourceFiles() +{ + for (const auto &dirName : CMD_dirList) + { + DIR *dirHandle = opendir(dirName.c_str()); + if (!dirHandle) bailOut(std::string("unable to open directory '") + dirName + "'"); + + struct dirent *dirEntry; + while ((dirEntry = readdir(dirHandle)) != nullptr) + { + const std::string fileName = dirEntry->d_name; + + // Filter-out files which are not assembler files, temporary, etc. + + if (fileName.length() < 3) continue; + if (fileName.front() == '#') continue; + if (fileName.front() == '~') continue; + if (fileName.substr(fileName.length() - 2) != ".s") continue; + + // Add file to the global list + + GLOBAL_sourceFiles.push_back(SourceFile(fileName, dirName)); + GLOBAL_maxFileNameLen = std::max(GLOBAL_maxFileNameLen, fileName.length()); + } + + closedir(dirHandle); + } + + if (GLOBAL_sourceFiles.empty()) bailOut("no source files found"); + + // Sort the file list by name, to provide deterministic results + + auto compare = [](const SourceFile &a, const SourceFile &b) -> bool { return a.fileName.compare(b.fileName) < 0; }; + GLOBAL_sourceFiles.sort(compare); +} + +void checkInputFileLabels() +{ + std::set usedLabels; + for (const auto &sourceFile : GLOBAL_sourceFiles) + { + if (usedLabels.count(sourceFile.label) != 0) + { + bailOut(std::string("input file '") + sourceFile.fileName + "' has a name too similar to another one"); + } + + usedLabels.insert(sourceFile.label); + } +} + +void calcRoutineSizes() +{ + const std::string nameBase = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_sizetest"; + + const std::string outFileName = nameBase + ".s"; + const std::string symFileName = nameBase + ".sym"; + + // Remove old files + + unlink(outFileName.c_str()); + unlink(symFileName.c_str()); + + // Write test file to determine routine sizes + + std::ofstream outFile(outFileName, std::fstream::out | std::fstream::trunc); + if (!outFile.good()) bailOut(std::string("can't open temporary file '") + outFileName + "'"); + + // Start at $100, so that no local data gets accesses using ZP addressing modes + // during this pass, which would otherwise upset things later + + outFile << std::endl << ".segment " << CMD_segName << " [start=$100, min=$100, max=$FFFF]" << std::endl; + + for (const auto &sourceFile : GLOBAL_sourceFiles) + { + outFile << std::endl << std::endl << std::endl << std::endl; + outFile << "// Source file: " << sourceFile.fileName << std::endl << std::endl; + outFile << LAB_OUT_START << sourceFile.label << ":" << std::endl << std::endl; + + outFile << std::string(sourceFile.content.begin(), sourceFile.content.end()); + + outFile << std::endl << std::endl; + outFile << LAB_OUT_END << sourceFile.label << ":" << std::endl; + } + + if (!outFile.good()) bailOut(std::string("error writing temporary file '") + outFileName + "'"); + outFile.close(); + + // All written - now launch the assembler + + const std::string cmd = ASM_CMD + outFileName + " -symbolfile -o /dev/null"; + std::cout << std::flush; + if (0 != system(cmd.c_str())) + { + bailOut("assembler running failed"); + } + + // Read addresses + + std::ifstream symFile; + symFile.open(symFileName); + if (!symFile.good()) bailOut(std::string("unable to open results file '") + symFileName + "'"); + + std::string line; + while (std::getline(symFile, line)) + { + bool startLabel; + + if (0 == line.compare(0, LAB_IN_START.size(), LAB_IN_START)) + { + line.erase(0, LAB_IN_START.length()); + startLabel = true; + } + else if (0 == line.compare(0, LAB_IN_END.size(), LAB_IN_END)) + { + line.erase(0, LAB_IN_END.length()); + startLabel = false; + } + else continue; + + // Decode address, write it into the object + + auto eqPos = line.rfind('='); + + auto address = strtol(line.substr(eqPos + 2).c_str(), nullptr ,16); + std::string refLabel = line.substr(0, eqPos); + + for (auto &sourceFile : GLOBAL_sourceFiles) + { + if (refLabel.compare(sourceFile.label) != 0) continue; + if (startLabel) + { + sourceFile.testAddrStart = address; + } + else + { + sourceFile.testAddrEnd = address; + } + } + } + + symFile.close(); + + // Calculate size of each and every routine + + for (auto &sourceFile : GLOBAL_sourceFiles) + { + if (sourceFile.testAddrStart <= 0 || sourceFile.testAddrEnd <= 0 || + sourceFile.testAddrStart > sourceFile.testAddrEnd) + { + bailOut(std::string("unable to determine code length in '") + sourceFile.fileName + "'"); + } + + sourceFile.codeLength = sourceFile.testAddrEnd - sourceFile.testAddrStart; + GLOBAL_totalRoutinesSize += sourceFile.codeLength; + } + + // Check whether total code size is sane + + if (0 == GLOBAL_totalRoutinesSize) bailOut("total code size is 0"); + if (signed(GLOBAL_totalRoutinesSize) > CMD_hiAddress - CMD_loAddress) + { + bailOut(std::string("total code size is ") + std::to_string(GLOBAL_totalRoutinesSize) + ", too much for this segment!"); + } + + // Sort the file list by code size, starting from the smallest + + auto compare = [](const SourceFile &a, const SourceFile &b) -> bool { return a.codeLength < b.codeLength; }; + GLOBAL_sourceFiles.sort(compare); + + // Move zero-sized element to a separate list + + while (GLOBAL_sourceFiles.front().codeLength == 0) + { + GLOBAL_sourceFiles_noCode.push_back(GLOBAL_sourceFiles.front()); + GLOBAL_sourceFiles.pop_front(); + } +} + +void prepareBinningProblem() +{ + // Prepare the log file + + const std::string logFileName = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_binproblem.log"; + unlink(logFileName.c_str()); + std::ofstream logFile(logFileName, std::fstream::out | std::fstream::trunc); + std::string logLine; + + // Print out code length information + + for (const auto &sourceFile : GLOBAL_sourceFiles) + { + std::string spacing; + spacing.resize(GLOBAL_maxFileNameLen + 4 - sourceFile.fileName.length(), ' '); + std::string floating = sourceFile.floating ? "(floating) " : " "; + logLine = "file: " + floating + sourceFile.fileName + spacing + "size: " + std::to_string(sourceFile.codeLength); + + logFile << logLine << std::endl; + std::cout << logLine << std::endl; + } + + // Create the binning problem + + GLOBAL_binningProblem = BinningProblem(CMD_loAddress, CMD_hiAddress); + + for (auto &sourceFile : GLOBAL_sourceFiles) + { + GLOBAL_binningProblem.addToProblem(&sourceFile); + } + + // Print out some more statistics + + logLine = "free space (after floating routines are placed): " + + std::to_string(CMD_hiAddress - CMD_loAddress - GLOBAL_totalRoutinesSize) ; + logFile << std::endl << logLine << std::endl; + std::cout << std::endl << logLine << std::endl; + logLine = "number of floating routines: " + + std::to_string(GLOBAL_binningProblem.floatingRoutines.size()); + logFile << logLine << std::endl; + std::cout << logLine << std::endl; + logLine = "number of gaps for the floating routines: " + + std::to_string(GLOBAL_binningProblem.gaps.size()); + logFile << logLine << std::endl << std::endl; + std::cout << logLine << std::endl << std::endl; + + // Print out the available gaps + + logLine = "gap address: $"; + for (auto& gap : GLOBAL_binningProblem.gaps) + { + std::string gapSize = std::string(" size: ") + std::to_string(gap.second); + logFile << logLine << std::uppercase << std::hex << gap.first << gapSize << std::endl; + std::cout << logLine << std::uppercase << std::hex << gap.first << gapSize << std::endl; + } + + std::cout << std::endl; + + // Close the log file + + if (!logFile.good()) bailOut(std::string("error writing log file '") + logFileName + "'"); + logFile.close(); +} + +void solveBinningProblem() +{ + std::cout << "trying to solve the routine binning problem" << std::endl << std::endl; + + // Do some routine actions on the binning problem object + + Solver solver(GLOBAL_binningProblem); + solver.run(); + + if (!GLOBAL_binningProblem.isSolved()) + { + bailOut("unable to solve the routine binning problem"); + } + + std::cout << std::endl; +} + +void compileSegment() +{ + // First combine everything into one assembler file + + const std::string outFileName = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_combined.s"; + unlink(outFileName.c_str()); + std::ofstream outFile(outFileName, std::fstream::out | std::fstream::trunc); + if (!outFile.good()) bailOut(std::string("can't open temporary file '") + outFileName + "'"); + + // Write the header + + outFile << std::endl << ".segment " << CMD_segName << + " [start=$" << std::hex << CMD_loAddress << + ", min=$" << std::hex << CMD_loAddress << + ", max=$" << std::hex << CMD_hiAddress << + ", outBin=\"" << CMD_outFile << "\", fill]" << + std::endl; + + // Write files which only contain definitions (no routines) + + for (const auto &sourceFile : GLOBAL_sourceFiles_noCode) + { + outFile << std::endl << std::endl << std::endl << std::endl; + outFile << "// Source file: " << sourceFile.fileName << std::endl << std::endl; + outFile << std::string(sourceFile.content.begin(), sourceFile.content.end()); + outFile << std::endl; + } + + // Write remaining files, these should be placed under their proper locations + + for (const auto &routine : GLOBAL_binningProblem.fixedRoutines) + { + outFile << std::endl << std::endl << std::endl << std::endl; + outFile << "// Source file: " << routine.second->fileName << std::endl << std::endl; + outFile << "\t* = $" << std::hex << routine.first << std::endl << std::endl; + outFile << std::string(routine.second->content.begin(), routine.second->content.end()); + outFile << std::endl; + } + + if (!outFile.good()) bailOut(std::string("error writing temporary file '") + outFileName + "'"); + outFile.close(); + + // All written - now launch the assembler + + const std::string cmd = ASM_CMD + outFileName + " -symbolfile -o " + CMD_outFile; + std::cout << std::flush; + if (0 != system(cmd.c_str())) + { + bailOut("assembler running failed"); + } +} + +// +// Main function +// + +int main(int argc, char **argv) +{ + parseCommandLine(argc, argv); + + printBannerCollectAnalyse(); + + readSourceFiles(); + checkInputFileLabels(); + calcRoutineSizes(); + + printBannerBinCompile(); + + prepareBinningProblem(); + solveBinningProblem(); + compileSegment(); + + return 0; +} + +// +// Class 'SourceFile' +// + +SourceFile::SourceFile(const std::string &fileName, const std::string &dirName) : + fileName(fileName), + dirName(dirName), + floating(false), + startAddr(-1), + codeLength(-1), + testAddrStart(-1), + testAddrEnd(-1) +{ + const std::string fileNameWithPath = dirName + DIR_SEPARATOR + fileName; + std::cout << "reading file: " << fileNameWithPath << std::endl; + + // Open the file + + std::ifstream inFile; + inFile.open(fileNameWithPath); + if (!inFile.good()) bailOut("unable to open file"); + + // Read the content + + inFile.seekg(0, inFile.end); + auto fileLength = inFile.tellg(); + if (fileLength == 0) bailOut("file is empty"); + content.resize(fileLength); + + inFile.seekg(0); + inFile.read(&content[0], fileLength); + if (!inFile.good()) bailOut("error reading file content"); + + inFile.close(); + + // Determine if the file content is floating or fixed position one, + // retrieve start address + + auto isHexDigit = [](char digit) -> bool + { + return (digit >= '0' && digit <= '9') || + (digit >= 'a' && digit <= 'f') || + (digit >= 'A' && digit <= 'F');; + }; + + floating = !(fileName.length() >= 6 && fileName[4] == '.' && + isHexDigit(fileName[0]) && + isHexDigit(fileName[1]) && + isHexDigit(fileName[2]) && + isHexDigit(fileName[3])); + + if (!floating) + { + startAddr = strtol(fileName.substr(0, 4).c_str(), nullptr ,16); + } + + // Generate KickAss compatible label from the file name + + label = fileName.substr(0, fileName.length() - 2); + + std::replace(label.begin(), label.end(), '.', '_'); + std::replace(label.begin(), label.end(), ',', '_'); +} + +// +// Class 'BinningProblem' +// + +BinningProblem::BinningProblem(int loAddress, int hiAddress) +{ + if (hiAddress < loAddress || hiAddress < 0 || loAddress < 0 || hiAddress > 0xFFFF || loAddress > 0xFFFF) + { + bailOut("invalid lo/hi address"); + } + + // Create one large gap (initial) to represent the assembly + + gaps[loAddress] = hiAddress - loAddress + 1; +} + +bool BinningProblem::isSolved() const +{ + return floatingRoutines.empty(); +} + +void BinningProblem::addToProblem(SourceFile *routine) +{ + if (routine->floating) + { + floatingRoutines.push_back(routine); + } + else + { + // For the fixed-address routines, we have to find the matching place + + bool gapFound = false; + for (auto &gap: gaps) + { + if (gap.first > routine->startAddr || gap.first + gap.second - 1 < routine->startAddr) + { + continue; // not a suitable gap + } + + // We have to put the routine into the current gap + + if (gap.first + gap.second < routine->startAddr + routine->codeLength) + { + bailOut(std::string("fixed address file '") + routine->fileName + "' won't fit in the available gap"); + } + + gapFound = true; + + // Put the routine into the gap, possibly removing it or splitting into two + + fixedRoutines[routine->startAddr] = routine; + + // Calculate possible new gap after the routine + + int newGapSize = (gap.first + gap.second) - (routine->startAddr + routine->codeLength); + int newGapStart = (newGapSize <= 0) ? -1 : routine->startAddr + routine->codeLength; + + // Remove or shrink the current gap + + if (gap.first == routine->startAddr) + { + gaps.erase(gap.first); + } + else + { + gap.second = routine->startAddr - gap.first; + } + + // Add a new gap + + if (newGapStart > 0) gaps[newGapStart] = newGapSize; + + break; // iterator is not valid enymore, we have to stop the llop + } + + if (!gapFound) + { + bailOut(std::string("start address of fixed address file '") + routine->fileName + "' already occupied"); + } + } +} + +void BinningProblem::fillGap(int gapAddress, const std::list &routines) +{ + int offset = 0; + std::string spacing; + + for (auto &routine : routines) + { + int targetAddr = gapAddress + offset; + + spacing.resize(GLOBAL_maxFileNameLen + 4 - routine->fileName.length(), ' '); + std::cout << " $" << std::hex << targetAddr << std::dec << ": " << + routine->fileName << spacing << "size: " << routine->codeLength << std::endl; + + fixedRoutines[targetAddr] = routine; + offset += routine->codeLength; + + if (offset > gaps[gapAddress]) bailOut(std::string("internal error line ") + std::to_string(__LINE__)); + + floatingRoutines.erase(std::remove(floatingRoutines.begin(), floatingRoutines.end(), routine), floatingRoutines.end()); + } + + // Get rid of the gap, it's useless now + + if (offset == gaps[gapAddress]) + { + std::cout << "filled to the last byte" << std::endl; + } + else if (!isSolved()) + { + std::cout << "filled in - dropped bytes: " << gaps[gapAddress] << std::endl; + } + else + { + std::cout << "out of routines" << std::endl; + } + + gaps.erase(gapAddress); +} + +void BinningProblem::performObviousSteps() +{ + // Get the size of the biggest routine; if there is just one gap which + // can handle it - put the roputine exactly there + + std::string spacing; + + bool repeat = true; + while (repeat && !floatingRoutines.empty() && !gaps.empty()) + { + repeat = false; + + int routineSize = floatingRoutines.back()->codeLength; + + int gapAddress; + int matchingGaps = 0; + for (auto &gap : gaps) + { + if (gap.second >= routineSize) + { + matchingGaps++; + gapAddress = gap.first; + } + } + + if (matchingGaps == 1) + { + // Routine can only be placed in this particular gap - do so + + gaps[gapAddress] -= routineSize; + int targetAddr = gapAddress + gaps[gapAddress]; + fixedRoutines[targetAddr] = floatingRoutines.back(); + + std::cout << "forced reducing gap $" << std::hex << gapAddress << std::dec << " to size " << + gaps[gapAddress] << std::endl; + + spacing.resize(GLOBAL_maxFileNameLen + 4 - floatingRoutines.back()->fileName.length(), ' '); + std::cout << " $" << std::hex << targetAddr << std::dec << ": " << + floatingRoutines.back()->fileName << spacing << "size: " << + floatingRoutines.back()->codeLength << std::endl; + + floatingRoutines.pop_back(); + if (gaps[gapAddress] == 0) gaps.erase(gapAddress); + + repeat = true; + } + } +} + +void BinningProblem::removeUselessGaps() +{ + // Get the size of the smallest floating routine, + // remove all the gaps which are smaller in size + + int minUsefulSize = floatingRoutines[0]->codeLength; + + bool repeat = true; + while (repeat) + { + repeat = false; + for (auto &gap : gaps) + { + if (gap.second < minUsefulSize) + { + std::cout << "dropping gap: $" << std::hex << gap.first << std::dec << " (size: " << gap.second << ")" << std::endl; + gaps.erase(gap.first); + repeat = true; + break; + } + } + } +} + +void BinningProblem::sortFloatingRoutinesBySize() +{ + // Sort the unallocated routines by size, starting from the smallest one + + auto compare = [](const SourceFile *a, const SourceFile *b) -> bool { return a->codeLength < b->codeLength; }; + std::sort (floatingRoutines.begin(), floatingRoutines.end(), compare); +} + +// +// Class 'Solver' +// + +void Solver::run() +{ + problem.sortFloatingRoutinesBySize(); // just to be extra sure + + while (!problem.gaps.empty() && !problem.floatingRoutines.empty()) + { + problem.performObviousSteps(); + problem.removeUselessGaps(); + + if (problem.gaps.empty() || problem.floatingRoutines.empty()) break; + + int gapAddr = selectGapToFill(); + + std::cout << "selected gap: " << "$" << std::hex << gapAddr << std::dec << " (size: " << problem.gaps[gapAddr] << ")" << std::endl; + + std::list partialSolution; + findPartialSolution(problem.gaps[gapAddr], partialSolution); + problem.fillGap(gapAddr, partialSolution); + } + + if (problem.isSolved()) + { + std::cout << std::endl << "all the routines sucessfully placed" << std::endl << std::endl; + } +} + +int Solver::selectGapToFill() +{ + // Find the smallest gap to fill-in + + int gapAddr = -1; + int gapSize = -1; + + for (auto &gap : problem.gaps) + { + if (gapSize < 0 || gap.second < gapSize) + { + gapAddr = gap.first; + gapSize = gap.second; + } + } + + return gapAddr; +} + +int KS(const std::vector &routines, + std::vector> &cacheV, // value cache + std::vector>> &cacheS, // partial solution cache + int n, int C, + std::list &solution) // sequence of decisions for each routine, has to be empty when calling +{ + // This routine solves a knapsack problem using a dynamic programming + + // XXX Possible efficiency improvement for the future: try to consider more than one gap at once, + // this will need a serious rework of the dynamic cache handling and will probably hurt the performance + + if (n == 0) + { + // No more routines to take the decision... + return 0; + } + + if (C == 0) + { + // We have no capacity left - decisions for all the routines left should be not to take them + solution.resize(n, false); + return 0; + } + + auto &cachedV = cacheV[n - 1][C - 1]; + auto &cachedS = cacheS[n - 1][C - 1]; + if (cachedV >= 0) + { + // We already hold the solution in out cache - return it + solution = cachedS; + return cachedV; + } + + auto &codeSize = routines[n - 1]->codeLength; + if (codeSize > C) + { + // We can't take this routine, it's too large + + cachedV = KS(routines, cacheV, cacheS, n - 1, C, solution); + solution.push_back(false); + cachedS = solution; + + return cachedV; + } + + // Note: it it seems equally good to take this routine, or not - take it! + // Evaluation starts from the largest routines, and we should prefer to leave + // a larger number of smaller routines - as this gives more possibilities + // while optimizing the usage of further gaps + + std::list solution1; + int val1 = KS(routines, cacheV, cacheS, n - 1, C - codeSize, solution1) + codeSize; // take + + if (val1 == C) + { + // By taking this routine we are filling all the space - contrary to the classic + // knapsack problem, this is an optimal solution for us, don't waste time calculating + // the others + + cachedV = val1; + solution = solution1; + solution.push_back(true); + cachedS = solution; + return cachedV; + } + + std::list solution2; + int val2 = KS(routines, cacheV, cacheS, n - 1, C, solution2); // don't take + + if (val1 >= val2) + { + // It's better to take this particular routine + + cachedV = val1; + solution = solution1; + solution.push_back(true); + } + else + { + // It's better not to take this particular routine + + cachedV = val2; + solution = solution2; + solution.push_back(false); + } + + cachedS = solution; + return cachedV; +}; + +void Solver::findPartialSolution(int gapSize, std::list &partialSolution) +{ + // First filter out available routines, take only the ones not larger than our gap + + std::vector routines; + routines.clear(); + for (auto &routine : problem.floatingRoutines) + { + if (routine->codeLength <= gapSize) + { + routines.push_back(routine); + } + else break; // 'floatingRoutines' should be kept sorted + } + + // Prepare value cache + + std::vector> cacheV; + cacheV.resize(routines.size()); + for (auto &cacheRow : cacheV) cacheRow.resize(gapSize, -1); + + // Prepare partial solution cache + std::vector>> cacheS; + cacheS.resize(routines.size()); + for (auto &cacheRow : cacheS) cacheRow.resize(gapSize); + + // Calculate solution + + std::list solution; + KS(routines, cacheV, cacheS, routines.size(), gapSize, solution); + + if (routines.size() != solution.size()) bailOut(std::string("internal error line ") + std::to_string(__LINE__)); + + // Return the solution upstream + + while (!routines.empty()) + { + if (solution.back() != false) + { + partialSolution.push_front(routines.back()); + } + + routines.pop_back(); + solution.pop_back(); + } + + return; +} diff --git a/src/compress_text.c b/src/compress_text.c index ff0cc4eb..cf7e4751 100644 --- a/src/compress_text.c +++ b/src/compress_text.c @@ -479,7 +479,7 @@ int main(void) } else printf("\t.byte $%02x\n",packed_keywords[i]); } - printf("\t.const packed_keyword_table_len = $%X\n",packedkey_len); + printf("\t.label packed_keyword_table_len = $%X\n",packedkey_len); fprintf(stderr,"Error list takes %d bytes raw.\n",raw_size); fprintf(stderr,"%d token bytes used to encode all messages.\n",token_count); diff --git a/src/basic005.c b/src/outdated/basic005.c similarity index 100% rename from src/basic005.c rename to src/outdated/basic005.c diff --git a/src/prepare_startup.c b/src/outdated/prepare_startup.c similarity index 100% rename from src/prepare_startup.c rename to src/outdated/prepare_startup.c diff --git a/src/preprocess.c b/src/outdated/preprocess.c similarity index 100% rename from src/preprocess.c rename to src/outdated/preprocess.c From 8de99f2b14a86dff95de7dd266d2d73afde03b01 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 9 Sep 2019 17:00:42 +0200 Subject: [PATCH 7/9] one more cleanup in aliases --- c64/aliases/,aliases_ram_lowmem.s | 26 +++++++++++++------------- c64/basic/,aliases.s | 2 -- c64/basic/basic_cold_start.s | 2 +- c64/kernal/,aliases.s | 2 -- c64/kernal/cint_real.s | 2 +- c64/kernal/close_load.s | 2 +- c64/kernal/f291.close.s | 2 +- c64/kernal/f4a5.load.s | 5 ++--- c64/kernal/fd15.vector.s | 2 +- c64/kernal/iec/iec_cmd_open.s | 2 +- c64/kernal/iec/iec_rx_byte.s | 4 ++-- c64/kernal/iec/iec_tx_byte.s | 6 +++--- c64/kernal/iec/iec_tx_command.s | 2 +- c64/kernal/lvs_helpers.s | 6 +++--- c64/kernal/memtop.s | 8 ++++---- c64/kernal/ramtas.s | 8 ++++---- c64/kernal/talk.s | 2 +- c64/kernal/untlk.s | 2 +- 18 files changed, 40 insertions(+), 45 deletions(-) diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index 8b116ec7..f7dd4ea0 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -39,7 +39,7 @@ .label STREND = $31 // $31-$32 -- NOT IMPLEMENTED -- .label FRETOP = $33 // $33-$34 -- NOT IMPLEMENTED -- .label FRESPC = $35 // $35-$36 [!] our implementation might be different XXX give more details - // .label MEMSIZ = $37 // $37-$38 -- NOT IMPLEMENTED -- highest address of BASIC memory XXX remove name conflict + .label MEMSIZ = $37 // $37-$38 -- NOT IMPLEMENTED -- highest address of BASIC memory .label CURLIN = $39 // $39-$3A current BASIC line number .label OLDLIN = $3B // $3B-$3C previous BASIC line number .label OLDTXT = $3D // $3D-$3E current BASIC line pointer @@ -75,7 +75,7 @@ .label IOSTATUS = $90 .label STKEY = $91 // Keys down clears bits. STOP - bit 7, C= - bit 6, SPACE - bit 4, CTRL - bit 2 .label SVXT = $92 // -- NOT IMPLEMENTED -- - .label VERCK = $93 // 0 = LOAD, 1 = VERIFY XXX rename to VERCKK + .label VERCKK = $93 // 0 = LOAD, 1 = VERIFY .label C3PO = $94 // flag - is BSOUR content valid .label BSOUR = $95 // serial bus buffered output byte .label SYNO = $96 // -- NOT IMPLEMENTED -- @@ -88,9 +88,9 @@ .label MSGFLG = $9D // bit 6 = error messages, bit 7 = control message .label PTR1 = $9E // -- NOT IMPLEMENTED -- .label PTR2 = $9F // -- NOT IMPLEMENTED -- - .label TIME = $A0 // $A0-$A2, jiffy clock - .label IEC_TMP1 = $A3 // temporary variable for tape and IEC, [!] our usage probably differs in details XXX rename to TSFCNT - .label IEC_TMP2 = $A4 // temporary variable for tape and IEC, [!] our usage probably differs in details XXX rename to TBTCNT + .label TIME = $A0 // $A0-$A2 jiffy clock + .label TSFCNT = $A3 // temporary variable for tape and IEC, [!] our usage probably differs in details + .label TBTCNT = $A4 // temporary variable for tape and IEC, [!] our usage probably differs in details .label CNTDN = $A5 // -- NOT IMPLEMENTED -- .label BUFPNT = $A6 // -- NOT IMPLEMENTED -- .label INBIT = $A7 // -- NOT IMPLEMENTED -- @@ -100,7 +100,7 @@ .label RIPRTY = $AB // -- NOT IMPLEMENTED -- .label SAL = $AC // $AC-$AD -- NOT IMPLEMENTED -- (implemented screen part) .label EAL = $AE // $AE-$AF -- NOT IMPLEMENTED -- [!] used also byy screen editor - .label CMP0 = $B0 // $B0-$B1, temporary tape storage, [!] here used for BRK instruction address + .label CMP0 = $B0 // $B0-$B1 temporary tape storage, [!] here used for BRK instruction address .label TAPE1 = $B2 // $B2-$B3 tape buffer pointer .label BITTS = $B4 // -- NOT IMPLEMENTED -- .label NXTBIT = $B5 // -- NOT IMPLEMENTED -- @@ -109,13 +109,13 @@ .label LA = $B8 // current logical_file number .label SA = $B9 // current secondary address .label FA = $BA // current device number - .label FNADDR = $BB // $BB-$BC, current file name pointer + .label FNADDR = $BB // $BB-$BC current file name pointer .label ROPRTY = $BD // -- NOT IMPLEMENTED -- .label FSBLK = $BE // -- NOT IMPLEMENTED -- .label MYCH = $BF // -- NOT IMPLEMENTED -- .label CAS1 = $C0 // -- NOT IMPLEMENTED -- - .label STAL = $C1 // $C1-$C2, LOAD/SAVE start address - .label MEMUS = $C3 // $C3-$C4, temporary address for tape LOAD/SAVE XXX rename to MEMUSS + .label STAL = $C1 // $C1-$C2 LOAD/SAVE start address + .label MEMUSS = $C3 // $C3-$C4 temporary address for tape LOAD/SAVE .label LSTX = $C5 // last keyy matrix position [!] our usage probably differs in details .label NDX = $C6 // number of chars in keyboard buffer .label RVS = $C7 // flag, whether to print reversed characters @@ -157,9 +157,9 @@ .label LAT = $259 // $259-$262, logical file numbers (table, 10 bytes) .label FAT = $263 // $263-$26C, device numbers (table, 10 bytes) .label SAT = $26D // $26D-$276, secondary addresses (table, 10 bytes) - .label KEYD = $277 // $277-$280 keyboard buffer - .label MEMSTR = $281 // $281-$282 XXX rename to LORAM - .label MEMSIZ = $283 // $283-$284, NOTE: Mapping the 64 erroneously has the hex as $282, while the DEC is correct XXX rename to HIRAM + .label KEYD = $277 // $277-$280, keyboard buffer + .label MEMSTR = $281 // $281-$282, start of BASIC memory + .label MEMEND = $283 // $283-$284, NOTE: Mapping the 64 erroneously has the hex as $282 (DEC is correct), name seems to be mistaken too .label TIMOUT = $285 // IEEE-488 timeout .label COLOR = $286 // current text foreground color .label GDCOL = $287 // color of character under cursor @@ -189,7 +189,7 @@ .label TRDTMP = $2A3 // -- NOT IMPLEMENTED -- .label TD1IRQ = $2A4 // -- NOT IMPLEMENTED -- .label TLNIDX = $2A5 // -- NOT IMPLEMENTED -- - .label PALNTSC = $2A6 // 0 = NTSC, 1 = PAL XXX rename to TVSFLG + .label TVSFLG = $2A6 // 0 = NTSC, 1 = PAL // [!] XXX document $2A7-$2FF usage // BASIC vectors diff --git a/c64/basic/,aliases.s b/c64/basic/,aliases.s index a626522d..2cd8b229 100644 --- a/c64/basic/,aliases.s +++ b/c64/basic/,aliases.s @@ -90,8 +90,6 @@ .label screen_line_link_table = $D9 .label current_screen_line_colour_ptr = $F3 .label keyboard_decoding_table_ptr = $F5 - .label rs232_rx_buffer_ptr = $F7 - .label rs232_tx_buffer_ptr = $F9 .label basic_input_buffer = BUF diff --git a/c64/basic/basic_cold_start.s b/c64/basic/basic_cold_start.s index ac1f507c..d3aab8fd 100644 --- a/c64/basic/basic_cold_start.s +++ b/c64/basic/basic_cold_start.s @@ -19,7 +19,7 @@ startup_banner: // Print PAL/NTSC ldx #30 // NTSC - lda PALNTSC + lda TVSFLG beq !+ ldx #31 // PAL !: diff --git a/c64/kernal/,aliases.s b/c64/kernal/,aliases.s index e2a275b5..0d133ed5 100644 --- a/c64/kernal/,aliases.s +++ b/c64/kernal/,aliases.s @@ -41,8 +41,6 @@ .label screen_line_link_table = $D9 .label current_screen_line_colour_ptr = $F3 .label keyboard_decoding_table_ptr = $F5 - .label rs232_rx_buffer_ptr = $F7 - .label rs232_tx_buffer_ptr = $F9 // "Compute's Mapping the 64" book .label keyboard_buffer = $0277 diff --git a/c64/kernal/cint_real.s b/c64/kernal/cint_real.s index 401db85c..97a4d701 100644 --- a/c64/kernal/cint_real.s +++ b/c64/kernal/cint_real.s @@ -54,7 +54,7 @@ cint_pal: lda #$01 !: - sta PALNTSC + sta TVSFLG cint_brk: // entry for BRK and STOP+RESTORE - XXX, where should it start? diff --git a/c64/kernal/close_load.s b/c64/kernal/close_load.s index b899cf21..efb0b013 100644 --- a/c64/kernal/close_load.s +++ b/c64/kernal/close_load.s @@ -13,7 +13,7 @@ close_load: jsr LISTEN lda #$E0 // CLOSE command - sta IEC_TMP2 + sta TBTCNT jsr iec_tx_command jsr iec_tx_command_finalize diff --git a/c64/kernal/f291.close.s b/c64/kernal/f291.close.s index 5b45bf47..ca60794b 100644 --- a/c64/kernal/f291.close.s +++ b/c64/kernal/f291.close.s @@ -34,7 +34,7 @@ CLOSE: jmp close_remove_from_table !: ora $E0 // CLOSE command - sta IEC_TMP2 + sta TBTCNT jsr iec_tx_command bcs close_remove_from_table jsr iec_tx_command_finalize diff --git a/c64/kernal/f4a5.load.s b/c64/kernal/f4a5.load.s index cbf0b1d7..bb43f88f 100644 --- a/c64/kernal/f4a5.load.s +++ b/c64/kernal/f4a5.load.s @@ -1,4 +1,3 @@ - // // Official Kernal routine, described in: // @@ -23,7 +22,7 @@ LOAD: // Are we loading or verifying? - sta VERCK + sta VERCKK // Store start address of LOAD stx STAL+0 @@ -82,7 +81,7 @@ LOAD: jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine !: lda #$60 // open channel / data (p3) , required according to p13 - sta IEC_TMP2 + sta TBTCNT jsr iec_tx_command bcc !+ jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine diff --git a/c64/kernal/fd15.vector.s b/c64/kernal/fd15.vector.s index eaad0ece..7b7fd00d 100644 --- a/c64/kernal/fd15.vector.s +++ b/c64/kernal/fd15.vector.s @@ -21,7 +21,7 @@ VECTOR: // Temporary storage location - checked on real C64 that this is the // address originally used; after calling VECTOR and checking zero page // area afterwards, the address could be found there - .label _caller_arr_ptr = MEMUS + .label _caller_arr_ptr = MEMUSS // According to 'Compute's Mapping the Commodore 64' page 237, // the CBM implementation does not disable IRQs - yet, the diff --git a/c64/kernal/iec/iec_cmd_open.s b/c64/kernal/iec/iec_cmd_open.s index 1d6389ab..5cc86ccb 100644 --- a/c64/kernal/iec/iec_cmd_open.s +++ b/c64/kernal/iec/iec_cmd_open.s @@ -18,7 +18,7 @@ iec_cmd_open: // similar to TKSA, but without turnaround common_open_close_unlsn_second: // common part of several commands - sta IEC_TMP2 + sta TBTCNT jsr iec_tx_command bcs !+ // branch if error jmp iec_tx_command_finalize diff --git a/c64/kernal/iec/iec_rx_byte.s b/c64/kernal/iec/iec_rx_byte.s index f0f17915..bb9328ef 100644 --- a/c64/kernal/iec/iec_rx_byte.s +++ b/c64/kernal/iec/iec_rx_byte.s @@ -135,12 +135,12 @@ iec_rx_clk_wait2: plp // Restore registers - sta IEC_TMP2 // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html + sta TBTCNT // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html pla tay pla tax - lda IEC_TMP2 + lda TBTCNT clc rts diff --git a/c64/kernal/iec/iec_tx_byte.s b/c64/kernal/iec/iec_tx_byte.s index bd561fb9..69e71f52 100644 --- a/c64/kernal/iec/iec_tx_byte.s +++ b/c64/kernal/iec/iec_tx_byte.s @@ -1,7 +1,7 @@ // Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc -// Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) +// Expects byte to send in TBTCNT ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) // Carry flag set = signal EOI // // Preserves .X and .Y registers @@ -53,9 +53,9 @@ iec_tx_common: iec_tx_common_sendbit: // Is next bit 0 or 1? - lda IEC_TMP2 + lda TBTCNT lsr - sta IEC_TMP2 + sta TBTCNT bcs !+ // Bit is 0 diff --git a/c64/kernal/iec/iec_tx_command.s b/c64/kernal/iec/iec_tx_command.s index 6965d1d0..42c98960 100644 --- a/c64/kernal/iec/iec_tx_command.s +++ b/c64/kernal/iec/iec_tx_command.s @@ -1,7 +1,7 @@ // Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc -// Expects byte to send in IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) +// Expects byte to send in TBTCNT ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) // Carry flag set = signal EOI // // Preserves .X and .Y registers diff --git a/c64/kernal/lvs_helpers.s b/c64/kernal/lvs_helpers.s index 2998b7e1..b4e20e98 100644 --- a/c64/kernal/lvs_helpers.s +++ b/c64/kernal/lvs_helpers.s @@ -18,7 +18,7 @@ lvs_send_file_name_loop: sec !: // Transmit one character - sta IEC_TMP2 + sta TBTCNT jsr iec_tx_byte jmp lvs_send_file_name_loop lvs_send_file_name_done: @@ -86,7 +86,7 @@ lvs_display_loading_verifying: // Display LOADING / VERIFYING and start address lda MSGFLG bpl lvs_display_end - lda VERCK + lda VERCKK beq !+ jsr printf // XXX don't use printf, use packed message .byte $0D @@ -156,7 +156,7 @@ lvs_illegal_device_number: lvs_load_verify_error: // XXX should we really return BASIC error code here? - lda VERCK + lda VERCKK bne lvs_verify_error lda #B_ERR_LOAD bne lvs_error_end diff --git a/c64/kernal/memtop.s b/c64/kernal/memtop.s index 1e244453..06995cf8 100644 --- a/c64/kernal/memtop.s +++ b/c64/kernal/memtop.s @@ -12,13 +12,13 @@ MEMTOP: bcc memtop_set - ldy MEMSIZ+1 - ldx MEMSIZ+0 + ldy MEMEND+1 + ldx MEMEND+0 rts memtop_set: - sty MEMSIZ+1 - stx MEMSIZ+0 + sty MEMEND+1 + stx MEMEND+0 rts diff --git a/c64/kernal/ramtas.s b/c64/kernal/ramtas.s index 4dddce03..d7481427 100644 --- a/c64/kernal/ramtas.s +++ b/c64/kernal/ramtas.s @@ -61,14 +61,14 @@ ramtas_l2: ldx #>$0400 stx HIBASE - // Work out RAM size and put in MEMSTR and MEMSIZ + // Work out RAM size and put in MEMSTR and MEMEND // "Compute's Mapping the 64", p54 // http://unusedino.de/ec64/technical/project64/mapping_c64.html ldx #>$0800 stx MEMSTR+1 ldx #$00 stx MEMSTR+0 - stx MEMSIZ+0 + stx MEMEND+0 // Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF lda $8000 eor #$FF @@ -79,12 +79,12 @@ ramtas_l2: beq ramtas_32K_RAM sta $8000 ldx #$A0 - stx MEMSIZ+1 + stx MEMEND+1 jmp ramtas_RAM_sized ramtas_32K_RAM: sta $8000 // in case RAM is hiding beneath a ROM ldx #$80 - stx MEMSIZ+1 + stx MEMEND+1 // Fall through ramtas_RAM_sized: diff --git a/c64/kernal/talk.s b/c64/kernal/talk.s index 556de7d9..f895e4fb 100644 --- a/c64/kernal/talk.s +++ b/c64/kernal/talk.s @@ -26,7 +26,7 @@ TALK: common_talk_listen: // common part of TALK and LISTEN - sta IEC_TMP2 + sta TBTCNT jmp iec_tx_command diff --git a/c64/kernal/untlk.s b/c64/kernal/untlk.s index e1d5ba59..758d36ef 100644 --- a/c64/kernal/untlk.s +++ b/c64/kernal/untlk.s @@ -21,7 +21,7 @@ UNTLK: common_untlk_tksa: // common part of UNTLK and TKSA - sta IEC_TMP2 + sta TBTCNT jsr iec_tx_command bcs !+ // branch if error // XXX - for TKSA, is it really the right place to do a turnaround? I've got some doubts From 53e4babbe34e32ab4f138b1d82b54e39ad03e1b6 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 9 Sep 2019 17:46:52 +0200 Subject: [PATCH 8/9] updates to the binning tool --- Makefile | 12 +- src/build_segment.cc | 1060 ++++++++++++++++++++++-------------------- 2 files changed, 569 insertions(+), 503 deletions(-) diff --git a/Makefile b/Makefile index 66226086..5f770905 100644 --- a/Makefile +++ b/Makefile @@ -84,9 +84,9 @@ build/chargen.rom: $(TOOL_PNGPREPARE) assets/8x8font.png # Dependencies - BASIC and KERNAL -build/target_generic/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_generic) $(foreach dir,$(SRCDIR_BASIC_generic),$(wildcard $(dir)/*.s)) build/,generated/gen_packed_messages.s -build/target_mega65/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_mega65) $(foreach dir,$(SRCDIR_BASIC_mega65),$(wildcard $(dir)/*.s)) build/,generated/gen_packed_messages.s -build/target_ultimate64/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_ultimate64) $(foreach dir,$(SRCDIR_BASIC_ultimate64),$(wildcard $(dir)/*.s)) build/,generated/gen_packed_messages.s +build/target_generic/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_generic) $(foreach dir,$(SRCDIR_BASIC_generic),$(wildcard $(dir)/*.s)) build/,generated/packed_messages.s +build/target_mega65/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_mega65) $(foreach dir,$(SRCDIR_BASIC_mega65),$(wildcard $(dir)/*.s)) build/,generated/packed_messages.s +build/target_ultimate64/OUTB.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_BASIC_ultimate64) $(foreach dir,$(SRCDIR_BASIC_ultimate64),$(wildcard $(dir)/*.s)) build/,generated/packed_messages.s build/target_generic/OUTK.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_KERNAL_generic) $(foreach dir,$(SRCDIR_KERNAL_generic),$(wildcard $(dir)/*.s)) build/target_mega65/OUTK.BIN: $(TOOL_ASSEMBLER) $(TOOL_BUILD_SEGMENT) $(SRCDIR_KERNAL_mega65) $(foreach dir,$(SRCDIR_KERNAL_mega65),$(wildcard $(dir)/*.s)) @@ -106,15 +106,15 @@ build/basic_ultimate64.rom: build/target_ultimate64/newrom # Rules - BASIC and KERNAL -build/,generated/gen_packed_messages.s: $(TOOL_COMPRESS_TEXT) +build/,generated/packed_messages.s: $(TOOL_COMPRESS_TEXT) @mkdir -p build/,generated - $(TOOL_COMPRESS_TEXT) > build/,generated/gen_packed_messages.s + $(TOOL_COMPRESS_TEXT) > build/,generated/packed_messages.s .PRECIOUS: build/target_%/OUTB.BIN build/target_%/OUTB.BIN: @mkdir -p build/target_$* @rm -f $@* build/target_$*/BASIC* - @$(TOOL_BUILD_SEGMENT) -s BASIC -i BASIC-$* -o OUTB.BIN -t build/target_$* -l a000 -h e4d2 $(SRCDIR_BASIC_$*) build/,generated + @$(TOOL_BUILD_SEGMENT) -s BASIC -i BASIC-$* -o OUTB.BIN -t build/target_$* -l a000 -h e4d2 $(SRCDIR_BASIC_$*) build/,generated/packed_messages.s .PRECIOUS: build/target_%/OUTK.BIN build/target_%/OUTK.BIN: diff --git a/src/build_segment.cc b/src/build_segment.cc index 3d658171..26667b1d 100644 --- a/src/build_segment.cc +++ b/src/build_segment.cc @@ -4,8 +4,11 @@ // #include +#include +#include #include #include +#include #include #include @@ -17,13 +20,14 @@ #include #include -#if defined(WIN32) || defined(_WIN32) - #define DIR_SEPARATOR "\\" -#else - #define DIR_SEPARATOR "/" -#endif +#if defined(WIN32) || defined(_WIN32) + #define DIR_SEPARATOR "\\" +#else + #define DIR_SEPARATOR "/" +#endif const std::string ASM_CMD = "java -jar assembler/KickAss.jar "; + const std::string LAB_OUT_START = "__routine_START_"; const std::string LAB_OUT_END = "__routine_END_"; const std::string LAB_IN_START = ".label __routine_START_"; @@ -42,53 +46,53 @@ std::string CMD_segInfo = "(unnamed)"; int CMD_loAddress = 0xC000; int CMD_hiAddress = 0xCFFF; -std::list CMD_dirList; +std::list CMD_inList; // // Common helper functions // -void bailOut() +void ERROR() { - exit(-1); + exit(-1); } -void bailOut(const std::string &message) +void ERROR(const std::string &message) { - std::cout << std::endl << "FATAL: " << message << std::endl << std::endl; - exit(-1); + std::cout << "\n" << "ERROR: " << message << "\n\n"; + exit(-1); } void printUsage() { - std::cout << std::endl << - "usage: build_segment [-o ] [-d ] [-t ]" << std::endl << - " [-l ] [-h ]" << std::endl << - " [-s ] [-i ] " << - std::endl << std::endl; + std::cout << "\n" << + "usage: build_segment [-o ] [-d ] [-t ]" << "\n" << + " [-l ] [-h ]" << "\n" << + " [-s ] [-i ] " << + "\n\n"; } void printBannerLineTop() { - std::cout << std::endl << std::endl << std::endl << BANNER_LINE << std::endl; + std::cout << "\n\n\n" << BANNER_LINE << "\n"; } void printBannerLineBottom() { - std::cout << BANNER_LINE << std::endl << std::endl; + std::cout << BANNER_LINE << "\n\n"; } void printBannerCollectAnalyse() { - printBannerLineTop(); - std::cout << "// Segment '" << CMD_segInfo << "' - collecting and analysing routines" << std::endl; - printBannerLineBottom(); + printBannerLineTop(); + std::cout << "// Segment '" << CMD_segInfo << "' - collecting and analysing routines" << "\n"; + printBannerLineBottom(); } void printBannerBinCompile() { - printBannerLineTop(); - std::cout << "// Segment '" << CMD_segInfo << "' - binning and compiling the assembly" << std::endl; + printBannerLineTop(); + std::cout << "// Segment '" << CMD_segInfo << "' - binning and compiling the assembly" << "\n"; printBannerLineBottom(); } @@ -96,16 +100,34 @@ void printBannerBinCompile() // Class definitions // +class DualStream +{ +public: + DualStream(std::ostream& str1, std::ostream& str2) : str1(str1), str2(str2) {} + + template DualStream &operator<<(const T& x) + { + str1 << x; + str2 << x; + + return *this; + } + +private: + std::ostream& str1; + std::ostream& str2; +}; + class SourceFile { public: - SourceFile(const std::string &fileName, const std::string &dirName); + SourceFile(const std::string &fileName, const std::string &dirName); - std::string fileName; - std::string dirName; + std::string fileName; + std::string dirName; bool floating; - std::vector content; + std::vector content; std::string label; int startAddr; // for fixed (non-floating) routines only @@ -119,35 +141,38 @@ class BinningProblem { public: - BinningProblem() {}; - BinningProblem(int loAddress, int hiAddress); + BinningProblem() {}; + BinningProblem(int loAddress, int hiAddress); - bool isSolved() const; + bool isSolved() const; - void addToProblem(SourceFile *routine); - void fillGap(int gapAddress, const std::list &routines); - void performObviousSteps(); - void removeUselessGaps(); - void sortFloatingRoutinesBySize(); + void addToProblem(SourceFile *routine); + void fillGap(DualStream &logOutput, int gapAddress, const std::list &routines); + void performObviousSteps(DualStream &logOutput); + void removeUselessGaps(DualStream &logOutput); + void sortFloatingRoutinesBySize(); - std::map fixedRoutines; // routines with location already fixed - std::map gaps; // gaps by address - std::vector floatingRoutines; // routines not allocated to any address yet; always keep them sorted! + std::map fixedRoutines; // routines with location already fixed + std::map gaps; // gaps by address + std::vector floatingRoutines; // routines not allocated to any address yet; always keep them sorted! }; class Solver { public: - Solver(BinningProblem &problem) : problem(problem) {} + Solver(BinningProblem &problem) : problem(problem), logOutput(logFile, std::cout) {} - void run(); + void run(); - int selectGapToFill(); - void findPartialSolution(int gapSize, std::list &partialSolution); + int selectGapToFill(); + void findPartialSolution(int gapSize, std::list &partialSolution); private: BinningProblem &problem; + std::ofstream logFile; + + DualStream logOutput; }; // @@ -166,119 +191,147 @@ BinningProblem GLOBAL_binningProblem; void parseCommandLine(int argc, char **argv) { - int opt; + int opt; - // Retrieve command line options + // Retrieve command line options while ((opt = getopt(argc, argv, "o:d:t:l:h:s:i:")) != -1) { switch(opt) { - case 'o': CMD_outFile = optarg; break; - case 't': CMD_tmpDir = optarg; break; - case 's': CMD_segName = optarg; break; - case 'i': CMD_segInfo = optarg; break; - case 'l': CMD_loAddress = strtol(optarg, nullptr ,16); break; - case 'h': CMD_hiAddress = strtol(optarg, nullptr ,16); break; - default: printUsage(); bailOut(); + case 'o': CMD_outFile = optarg; break; + case 't': CMD_tmpDir = optarg; break; + case 's': CMD_segName = optarg; break; + case 'i': CMD_segInfo = optarg; break; + case 'l': CMD_loAddress = strtol(optarg, nullptr ,16); break; + case 'h': CMD_hiAddress = strtol(optarg, nullptr ,16); break; + default: printUsage(); ERROR(); } } - // Retrieve directory list + // Retrieve file/directory list for (int idx = optind; idx < argc; idx++) { - CMD_dirList.push_back(argv[idx]); + CMD_inList.push_back(argv[idx]); } - if (CMD_dirList.empty()) { printUsage(); bailOut("empty directory list"); } + if (CMD_inList.empty()) { printUsage(); ERROR("empty directory/file list"); } } void readSourceFiles() { - for (const auto &dirName : CMD_dirList) - { - DIR *dirHandle = opendir(dirName.c_str()); - if (!dirHandle) bailOut(std::string("unable to open directory '") + dirName + "'"); + struct stat statBuf; + for (const auto &objName : CMD_inList) + { + if (stat(objName.c_str(), &statBuf) < 0) + { + ERROR(std::string("can't get information about '") + objName + "'"); + } - struct dirent *dirEntry; + if (S_ISREG(statBuf.st_mode)) + { + // This is a regular file + + char *tmp1 = strdup(objName.c_str()); + char *tmp2 = strdup(objName.c_str()); + + std::string dirName = dirname(tmp1); + std::string fileName = basename(tmp2); + + free(tmp1); + free(tmp2); + + GLOBAL_sourceFiles.push_back(SourceFile(fileName, dirName)); + GLOBAL_maxFileNameLen = std::max(GLOBAL_maxFileNameLen, fileName.length()); + continue; + } + + // This should be a directory + + DIR *dirHandle = opendir(objName.c_str()); + if (!dirHandle) ERROR(std::string("unable to open directory '") + objName + "'"); + + struct dirent *dirEntry; while ((dirEntry = readdir(dirHandle)) != nullptr) { - const std::string fileName = dirEntry->d_name; + const std::string fileName = dirEntry->d_name; // Filter-out files which are not assembler files, temporary, etc. - if (fileName.length() < 3) continue; + if (fileName.length() < 3) continue; if (fileName.front() == '#') continue; if (fileName.front() == '~') continue; if (fileName.substr(fileName.length() - 2) != ".s") continue; // Add file to the global list - GLOBAL_sourceFiles.push_back(SourceFile(fileName, dirName)); + GLOBAL_sourceFiles.push_back(SourceFile(fileName, objName)); GLOBAL_maxFileNameLen = std::max(GLOBAL_maxFileNameLen, fileName.length()); } closedir(dirHandle); - } + } - if (GLOBAL_sourceFiles.empty()) bailOut("no source files found"); + if (GLOBAL_sourceFiles.empty()) ERROR("no source files found"); - // Sort the file list by name, to provide deterministic results + // Sort the file list by name, to provide deterministic results - auto compare = [](const SourceFile &a, const SourceFile &b) -> bool { return a.fileName.compare(b.fileName) < 0; }; - GLOBAL_sourceFiles.sort(compare); + auto compare = [](const SourceFile &a, const SourceFile &b) -> bool { return a.fileName.compare(b.fileName) < 0; }; + GLOBAL_sourceFiles.sort(compare); } void checkInputFileLabels() { - std::set usedLabels; - for (const auto &sourceFile : GLOBAL_sourceFiles) - { - if (usedLabels.count(sourceFile.label) != 0) - { - bailOut(std::string("input file '") + sourceFile.fileName + "' has a name too similar to another one"); - } + std::set usedLabels; + for (const auto &sourceFile : GLOBAL_sourceFiles) + { + if (usedLabels.count(sourceFile.label) != 0) + { + ERROR(std::string("input file '") + sourceFile.fileName + "' has a name too similar to another one"); + } - usedLabels.insert(sourceFile.label); - } + usedLabels.insert(sourceFile.label); + } } void calcRoutineSizes() { - const std::string nameBase = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_sizetest"; + const std::string nameBase = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_sizetest"; const std::string outFileName = nameBase + ".s"; const std::string symFileName = nameBase + ".sym"; - // Remove old files + // Remove old files - unlink(outFileName.c_str()); - unlink(symFileName.c_str()); + unlink(outFileName.c_str()); + unlink(symFileName.c_str()); - // Write test file to determine routine sizes + // Write test file to determine routine sizes std::ofstream outFile(outFileName, std::fstream::out | std::fstream::trunc); - if (!outFile.good()) bailOut(std::string("can't open temporary file '") + outFileName + "'"); + if (!outFile.good()) ERROR(std::string("can't open temporary file '") + outFileName + "'"); // Start at $100, so that no local data gets accesses using ZP addressing modes // during this pass, which would otherwise upset things later - outFile << std::endl << ".segment " << CMD_segName << " [start=$100, min=$100, max=$FFFF]" << std::endl; + outFile << "\n" << ".segment " << CMD_segName << " [start=$100, min=$100, max=$FFFF]" << "\n"; + outFile << "#define BUILD_" << CMD_segName << "\n"; for (const auto &sourceFile : GLOBAL_sourceFiles) { - outFile << std::endl << std::endl << std::endl << std::endl; - outFile << "// Source file: " << sourceFile.fileName << std::endl << std::endl; - outFile << LAB_OUT_START << sourceFile.label << ":" << std::endl << std::endl; + outFile << "\n\n\n\n"; + outFile << "/* Source file: " << sourceFile.fileName << " */" << "\n\n"; + outFile << ".memblock \"" << sourceFile.fileName << "\"" << "\n"; + outFile << LAB_OUT_START << sourceFile.label << ":" << "\n\n"; - outFile << std::string(sourceFile.content.begin(), sourceFile.content.end()); + outFile << std::string(sourceFile.content.begin(), sourceFile.content.end()); - outFile << std::endl << std::endl; - outFile << LAB_OUT_END << sourceFile.label << ":" << std::endl; + outFile << "\n\n"; + outFile << LAB_OUT_END << sourceFile.label << ":" << "\n"; } - if (!outFile.good()) bailOut(std::string("error writing temporary file '") + outFileName + "'"); + if (!outFile.good()) ERROR(std::string("error writing temporary file '") + outFileName + "'"); outFile.close(); // All written - now launch the assembler @@ -287,112 +340,110 @@ void calcRoutineSizes() std::cout << std::flush; if (0 != system(cmd.c_str())) { - bailOut("assembler running failed"); + ERROR("assembler running failed"); } // Read addresses - std::ifstream symFile; + std::ifstream symFile; symFile.open(symFileName); - if (!symFile.good()) bailOut(std::string("unable to open results file '") + symFileName + "'"); + if (!symFile.good()) ERROR(std::string("unable to open results file '") + symFileName + "'"); - std::string line; - while (std::getline(symFile, line)) - { - bool startLabel; + std::string line; + while (std::getline(symFile, line)) + { + bool startLabel; - if (0 == line.compare(0, LAB_IN_START.size(), LAB_IN_START)) - { - line.erase(0, LAB_IN_START.length()); - startLabel = true; - } - else if (0 == line.compare(0, LAB_IN_END.size(), LAB_IN_END)) - { - line.erase(0, LAB_IN_END.length()); - startLabel = false; - } - else continue; + if (0 == line.compare(0, LAB_IN_START.size(), LAB_IN_START)) + { + line.erase(0, LAB_IN_START.length()); + startLabel = true; + } + else if (0 == line.compare(0, LAB_IN_END.size(), LAB_IN_END)) + { + line.erase(0, LAB_IN_END.length()); + startLabel = false; + } + else continue; - // Decode address, write it into the object + // Decode address, write it into the object - auto eqPos = line.rfind('='); + auto eqPos = line.rfind('='); - auto address = strtol(line.substr(eqPos + 2).c_str(), nullptr ,16); - std::string refLabel = line.substr(0, eqPos); + auto address = strtol(line.substr(eqPos + 2).c_str(), nullptr ,16); + std::string refLabel = line.substr(0, eqPos); - for (auto &sourceFile : GLOBAL_sourceFiles) - { - if (refLabel.compare(sourceFile.label) != 0) continue; - if (startLabel) - { - sourceFile.testAddrStart = address; - } - else - { - sourceFile.testAddrEnd = address; - } - } - } + for (auto &sourceFile : GLOBAL_sourceFiles) + { + if (refLabel.compare(sourceFile.label) != 0) continue; + if (startLabel) + { + sourceFile.testAddrStart = address; + } + else + { + sourceFile.testAddrEnd = address; + } + } + } symFile.close(); // Calculate size of each and every routine for (auto &sourceFile : GLOBAL_sourceFiles) - { - if (sourceFile.testAddrStart <= 0 || sourceFile.testAddrEnd <= 0 || - sourceFile.testAddrStart > sourceFile.testAddrEnd) - { - bailOut(std::string("unable to determine code length in '") + sourceFile.fileName + "'"); - } + { + if (sourceFile.testAddrStart <= 0 || sourceFile.testAddrEnd <= 0 || + sourceFile.testAddrStart > sourceFile.testAddrEnd) + { + ERROR(std::string("unable to determine code length in '") + sourceFile.fileName + "'"); + } - sourceFile.codeLength = sourceFile.testAddrEnd - sourceFile.testAddrStart; - GLOBAL_totalRoutinesSize += sourceFile.codeLength; - } + sourceFile.codeLength = sourceFile.testAddrEnd - sourceFile.testAddrStart; + GLOBAL_totalRoutinesSize += sourceFile.codeLength; + } - // Check whether total code size is sane + // Check whether total code size is sane - if (0 == GLOBAL_totalRoutinesSize) bailOut("total code size is 0"); - if (signed(GLOBAL_totalRoutinesSize) > CMD_hiAddress - CMD_loAddress) - { - bailOut(std::string("total code size is ") + std::to_string(GLOBAL_totalRoutinesSize) + ", too much for this segment!"); - } + if (0 == GLOBAL_totalRoutinesSize) ERROR("total code size is 0"); + if (signed(GLOBAL_totalRoutinesSize) > CMD_hiAddress - CMD_loAddress) + { + ERROR(std::string("total code size is ") + std::to_string(GLOBAL_totalRoutinesSize) + ", too much for this segment!"); + } - // Sort the file list by code size, starting from the smallest + // Sort the file list by code size, starting from the smallest - auto compare = [](const SourceFile &a, const SourceFile &b) -> bool { return a.codeLength < b.codeLength; }; - GLOBAL_sourceFiles.sort(compare); + auto compare = [](const SourceFile &a, const SourceFile &b) -> bool { return a.codeLength < b.codeLength; }; + GLOBAL_sourceFiles.sort(compare); - // Move zero-sized element to a separate list + // Move zero-sized element to a separate list - while (GLOBAL_sourceFiles.front().codeLength == 0) - { - GLOBAL_sourceFiles_noCode.push_back(GLOBAL_sourceFiles.front()); - GLOBAL_sourceFiles.pop_front(); - } + while (GLOBAL_sourceFiles.front().codeLength == 0) + { + GLOBAL_sourceFiles_noCode.push_back(GLOBAL_sourceFiles.front()); + GLOBAL_sourceFiles.pop_front(); + } } void prepareBinningProblem() { - // Prepare the log file + // Prepare the log file - const std::string logFileName = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_binproblem.log"; - unlink(logFileName.c_str()); - std::ofstream logFile(logFileName, std::fstream::out | std::fstream::trunc); - std::string logLine; + const std::string logFileName = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_binproblem.log"; + unlink(logFileName.c_str()); + std::ofstream logFile(logFileName, std::fstream::out | std::fstream::trunc); + DualStream logOutput(logFile, std::cout); - // Print out code length information + // Print out code length information - for (const auto &sourceFile : GLOBAL_sourceFiles) - { - std::string spacing; - spacing.resize(GLOBAL_maxFileNameLen + 4 - sourceFile.fileName.length(), ' '); - std::string floating = sourceFile.floating ? "(floating) " : " "; - logLine = "file: " + floating + sourceFile.fileName + spacing + "size: " + std::to_string(sourceFile.codeLength); + for (const auto &sourceFile : GLOBAL_sourceFiles) + { + std::string spacing; + spacing.resize(GLOBAL_maxFileNameLen + 4 - sourceFile.fileName.length(), ' '); + std::string floating = sourceFile.floating ? "(floating) " : " "; - logFile << logLine << std::endl; - std::cout << logLine << std::endl; - } + logOutput << "file: " << floating << sourceFile.fileName << spacing << "size: " << std::to_string(sourceFile.codeLength) << "\n"; + } // Create the binning problem @@ -400,99 +451,97 @@ void prepareBinningProblem() for (auto &sourceFile : GLOBAL_sourceFiles) { - GLOBAL_binningProblem.addToProblem(&sourceFile); + GLOBAL_binningProblem.addToProblem(&sourceFile); } // Print out some more statistics - logLine = "free space (after floating routines are placed): " + - std::to_string(CMD_hiAddress - CMD_loAddress - GLOBAL_totalRoutinesSize) ; - logFile << std::endl << logLine << std::endl; - std::cout << std::endl << logLine << std::endl; - logLine = "number of floating routines: " + - std::to_string(GLOBAL_binningProblem.floatingRoutines.size()); - logFile << logLine << std::endl; - std::cout << logLine << std::endl; - logLine = "number of gaps for the floating routines: " + - std::to_string(GLOBAL_binningProblem.gaps.size()); - logFile << logLine << std::endl << std::endl; - std::cout << logLine << std::endl << std::endl; + logOutput << "\n" << + "free space (after floating routines are placed): " << + std::to_string(CMD_hiAddress - CMD_loAddress - GLOBAL_totalRoutinesSize) << "\n" << + "number of floating routines: " << + std::to_string(GLOBAL_binningProblem.floatingRoutines.size()) << "\n" << + "number of gaps for the floating routines: " << + std::to_string(GLOBAL_binningProblem.gaps.size()) << "\n" << + "\n"; // Print out the available gaps - logLine = "gap address: $"; for (auto& gap : GLOBAL_binningProblem.gaps) { - std::string gapSize = std::string(" size: ") + std::to_string(gap.second); - logFile << logLine << std::uppercase << std::hex << gap.first << gapSize << std::endl; - std::cout << logLine << std::uppercase << std::hex << gap.first << gapSize << std::endl; + logOutput << "gap address: $" << std::uppercase << std::hex << gap.first << + " size: " << std::to_string(gap.second) << "\n"; } - std::cout << std::endl; + logOutput << "\n"; // Close the log file - if (!logFile.good()) bailOut(std::string("error writing log file '") + logFileName + "'"); - logFile.close(); + if (!logFile.good()) ERROR(std::string("error writing log file '") + logFileName + "'"); + logFile.close(); } void solveBinningProblem() { - std::cout << "trying to solve the routine binning problem" << std::endl << std::endl; + std::cout << "trying to solve the routine binning problem" << "\n\n"; - // Do some routine actions on the binning problem object + // Do some routine actions on the binning problem object - Solver solver(GLOBAL_binningProblem); - solver.run(); + Solver solver(GLOBAL_binningProblem); + solver.run(); - if (!GLOBAL_binningProblem.isSolved()) - { - bailOut("unable to solve the routine binning problem"); - } + if (!GLOBAL_binningProblem.isSolved()) + { + ERROR("unable to solve the routine binning problem"); + } - std::cout << std::endl; + std::cout << "\n"; } void compileSegment() { - // First combine everything into one assembler file + // First combine everything into one assembler file - const std::string outFileName = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_combined.s"; - unlink(outFileName.c_str()); - std::ofstream outFile(outFileName, std::fstream::out | std::fstream::trunc); - if (!outFile.good()) bailOut(std::string("can't open temporary file '") + outFileName + "'"); + const std::string outFileName = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_combined.s"; + unlink(outFileName.c_str()); + std::ofstream outFile(outFileName, std::fstream::out | std::fstream::trunc); + if (!outFile.good()) ERROR(std::string("can't open temporary file '") + outFileName + "'"); - // Write the header + // Write the header - outFile << std::endl << ".segment " << CMD_segName << - " [start=$" << std::hex << CMD_loAddress << - ", min=$" << std::hex << CMD_loAddress << - ", max=$" << std::hex << CMD_hiAddress << - ", outBin=\"" << CMD_outFile << "\", fill]" << - std::endl; + outFile << "\n" << + ".segment " << CMD_segName << + " [start=$" << std::hex << CMD_loAddress << + ", min=$" << std::hex << CMD_loAddress << + ", max=$" << std::hex << CMD_hiAddress << + ", outBin=\"" << CMD_outFile << "\", fill]" << + "\n"; + outFile << "#define BUILD_" << CMD_segName << "\n"; - // Write files which only contain definitions (no routines) + // Write files which only contain definitions (no routines) for (const auto &sourceFile : GLOBAL_sourceFiles_noCode) { - outFile << std::endl << std::endl << std::endl << std::endl; - outFile << "// Source file: " << sourceFile.fileName << std::endl << std::endl; - outFile << std::string(sourceFile.content.begin(), sourceFile.content.end()); - outFile << std::endl; + outFile << "\n\n\n\n"; + outFile << "/* Source file: " << sourceFile.fileName << " */" << "\n\n"; + outFile << ".memblock \"" << sourceFile.fileName << "\"" << "\n"; + outFile << std::string(sourceFile.content.begin(), sourceFile.content.end()); + outFile << "\n"; } // Write remaining files, these should be placed under their proper locations for (const auto &routine : GLOBAL_binningProblem.fixedRoutines) { - outFile << std::endl << std::endl << std::endl << std::endl; - outFile << "// Source file: " << routine.second->fileName << std::endl << std::endl; - outFile << "\t* = $" << std::hex << routine.first << std::endl << std::endl; - outFile << std::string(routine.second->content.begin(), routine.second->content.end()); - outFile << std::endl; + outFile << "\n\n\n\n"; + outFile << "/* Source file: " << routine.second->fileName << " */" << "\n\n"; + outFile << ".memblock \"" << routine.second->fileName << "\"" << "\n"; + outFile << "\t* = $" << std::hex << routine.first << "\n\n"; + outFile << std::string(routine.second->content.begin(), routine.second->content.end()); + outFile << "\n"; } - if (!outFile.good()) bailOut(std::string("error writing temporary file '") + outFileName + "'"); + if (!outFile.good()) ERROR(std::string("error writing temporary file '") + outFileName + "'"); outFile.close(); // All written - now launch the assembler @@ -501,7 +550,7 @@ void compileSegment() std::cout << std::flush; if (0 != system(cmd.c_str())) { - bailOut("assembler running failed"); + ERROR("assembler running failed"); } } @@ -511,21 +560,21 @@ void compileSegment() int main(int argc, char **argv) { - parseCommandLine(argc, argv); + parseCommandLine(argc, argv); - printBannerCollectAnalyse(); + printBannerCollectAnalyse(); - readSourceFiles(); - checkInputFileLabels(); - calcRoutineSizes(); + readSourceFiles(); + checkInputFileLabels(); + calcRoutineSizes(); - printBannerBinCompile(); + printBannerBinCompile(); - prepareBinningProblem(); - solveBinningProblem(); - compileSegment(); + prepareBinningProblem(); + solveBinningProblem(); + compileSegment(); - return 0; + return 0; } // @@ -541,25 +590,25 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName) testAddrStart(-1), testAddrEnd(-1) { - const std::string fileNameWithPath = dirName + DIR_SEPARATOR + fileName; - std::cout << "reading file: " << fileNameWithPath << std::endl; + const std::string fileNameWithPath = dirName + DIR_SEPARATOR + fileName; + std::cout << "reading file: " << fileNameWithPath << "\n"; - // Open the file + // Open the file - std::ifstream inFile; + std::ifstream inFile; inFile.open(fileNameWithPath); - if (!inFile.good()) bailOut("unable to open file"); + if (!inFile.good()) ERROR("unable to open file"); // Read the content inFile.seekg(0, inFile.end); auto fileLength = inFile.tellg(); - if (fileLength == 0) bailOut("file is empty"); + if (fileLength == 0) ERROR("file is empty"); content.resize(fileLength); inFile.seekg(0); inFile.read(&content[0], fileLength); - if (!inFile.good()) bailOut("error reading file content"); + if (!inFile.good()) ERROR("error reading file content"); inFile.close(); @@ -568,20 +617,20 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName) auto isHexDigit = [](char digit) -> bool { - return (digit >= '0' && digit <= '9') || - (digit >= 'a' && digit <= 'f') || - (digit >= 'A' && digit <= 'F');; + return (digit >= '0' && digit <= '9') || + (digit >= 'a' && digit <= 'f') || + (digit >= 'A' && digit <= 'F');; }; floating = !(fileName.length() >= 6 && fileName[4] == '.' && - isHexDigit(fileName[0]) && - isHexDigit(fileName[1]) && - isHexDigit(fileName[2]) && - isHexDigit(fileName[3])); + isHexDigit(fileName[0]) && + isHexDigit(fileName[1]) && + isHexDigit(fileName[2]) && + isHexDigit(fileName[3])); if (!floating) { - startAddr = strtol(fileName.substr(0, 4).c_str(), nullptr ,16); + startAddr = strtol(fileName.substr(0, 4).c_str(), nullptr ,16); } // Generate KickAss compatible label from the file name @@ -598,200 +647,200 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName) BinningProblem::BinningProblem(int loAddress, int hiAddress) { - if (hiAddress < loAddress || hiAddress < 0 || loAddress < 0 || hiAddress > 0xFFFF || loAddress > 0xFFFF) - { - bailOut("invalid lo/hi address"); - } + if (hiAddress < loAddress || hiAddress < 0 || loAddress < 0 || hiAddress > 0xFFFF || loAddress > 0xFFFF) + { + ERROR("invalid lo/hi address"); + } - // Create one large gap (initial) to represent the assembly + // Create one large gap (initial) to represent the assembly - gaps[loAddress] = hiAddress - loAddress + 1; + gaps[loAddress] = hiAddress - loAddress + 1; } bool BinningProblem::isSolved() const { - return floatingRoutines.empty(); + return floatingRoutines.empty(); } void BinningProblem::addToProblem(SourceFile *routine) { - if (routine->floating) - { - floatingRoutines.push_back(routine); - } - else - { - // For the fixed-address routines, we have to find the matching place + if (routine->floating) + { + floatingRoutines.push_back(routine); + } + else + { + // For the fixed-address routines, we have to find the matching place - bool gapFound = false; - for (auto &gap: gaps) - { - if (gap.first > routine->startAddr || gap.first + gap.second - 1 < routine->startAddr) - { - continue; // not a suitable gap - } + bool gapFound = false; + for (auto &gap: gaps) + { + if (gap.first > routine->startAddr || gap.first + gap.second - 1 < routine->startAddr) + { + continue; // not a suitable gap + } - // We have to put the routine into the current gap + // We have to put the routine into the current gap - if (gap.first + gap.second < routine->startAddr + routine->codeLength) - { - bailOut(std::string("fixed address file '") + routine->fileName + "' won't fit in the available gap"); - } + if (gap.first + gap.second < routine->startAddr + routine->codeLength) + { + ERROR(std::string("fixed address file '") + routine->fileName + "' won't fit in the available gap"); + } - gapFound = true; + gapFound = true; - // Put the routine into the gap, possibly removing it or splitting into two + // Put the routine into the gap, possibly removing it or splitting into two - fixedRoutines[routine->startAddr] = routine; + fixedRoutines[routine->startAddr] = routine; - // Calculate possible new gap after the routine + // Calculate possible new gap after the routine - int newGapSize = (gap.first + gap.second) - (routine->startAddr + routine->codeLength); - int newGapStart = (newGapSize <= 0) ? -1 : routine->startAddr + routine->codeLength; + int newGapSize = (gap.first + gap.second) - (routine->startAddr + routine->codeLength); + int newGapStart = (newGapSize <= 0) ? -1 : routine->startAddr + routine->codeLength; - // Remove or shrink the current gap + // Remove or shrink the current gap - if (gap.first == routine->startAddr) - { - gaps.erase(gap.first); - } - else - { - gap.second = routine->startAddr - gap.first; - } + if (gap.first == routine->startAddr) + { + gaps.erase(gap.first); + } + else + { + gap.second = routine->startAddr - gap.first; + } - // Add a new gap + // Add a new gap - if (newGapStart > 0) gaps[newGapStart] = newGapSize; + if (newGapStart > 0) gaps[newGapStart] = newGapSize; break; // iterator is not valid enymore, we have to stop the llop - } + } - if (!gapFound) - { - bailOut(std::string("start address of fixed address file '") + routine->fileName + "' already occupied"); - } - } + if (!gapFound) + { + ERROR(std::string("start address of fixed address file '") + routine->fileName + "' already occupied"); + } + } } -void BinningProblem::fillGap(int gapAddress, const std::list &routines) +void BinningProblem::fillGap(DualStream &logOutput, int gapAddress, const std::list &routines) { - int offset = 0; - std::string spacing; + int offset = 0; + std::string spacing; - for (auto &routine : routines) - { - int targetAddr = gapAddress + offset; + for (auto &routine : routines) + { + int targetAddr = gapAddress + offset; - spacing.resize(GLOBAL_maxFileNameLen + 4 - routine->fileName.length(), ' '); - std::cout << " $" << std::hex << targetAddr << std::dec << ": " << - routine->fileName << spacing << "size: " << routine->codeLength << std::endl; + spacing.resize(GLOBAL_maxFileNameLen + 4 - routine->fileName.length(), ' '); + logOutput << " $" << std::hex << targetAddr << std::dec << ": " << + routine->fileName << spacing << "size: " << routine->codeLength << "\n"; fixedRoutines[targetAddr] = routine; offset += routine->codeLength; - if (offset > gaps[gapAddress]) bailOut(std::string("internal error line ") + std::to_string(__LINE__)); + if (offset > gaps[gapAddress]) ERROR(std::string("internal error line ") + std::to_string(__LINE__)); floatingRoutines.erase(std::remove(floatingRoutines.begin(), floatingRoutines.end(), routine), floatingRoutines.end()); - } + } - // Get rid of the gap, it's useless now + // Get rid of the gap, it's useless now - if (offset == gaps[gapAddress]) + if (offset == gaps[gapAddress]) { - std::cout << "filled to the last byte" << std::endl; + logOutput << "filled to the last byte" << "\n"; } else if (!isSolved()) { - std::cout << "filled in - dropped bytes: " << gaps[gapAddress] << std::endl; + logOutput << "filled in - dropped bytes: " << gaps[gapAddress] << "\n"; } else { - std::cout << "out of routines" << std::endl; + logOutput << "out of routines" << "\n"; } - gaps.erase(gapAddress); + gaps.erase(gapAddress); } -void BinningProblem::performObviousSteps() +void BinningProblem::performObviousSteps(DualStream &logOutput) { - // Get the size of the biggest routine; if there is just one gap which - // can handle it - put the roputine exactly there + // Get the size of the biggest routine; if there is just one gap which + // can handle it - put the roputine exactly there - std::string spacing; + std::string spacing; - bool repeat = true; - while (repeat && !floatingRoutines.empty() && !gaps.empty()) - { - repeat = false; + bool repeat = true; + while (repeat && !floatingRoutines.empty() && !gaps.empty()) + { + repeat = false; - int routineSize = floatingRoutines.back()->codeLength; + int routineSize = floatingRoutines.back()->codeLength; - int gapAddress; - int matchingGaps = 0; - for (auto &gap : gaps) - { - if (gap.second >= routineSize) - { - matchingGaps++; - gapAddress = gap.first; - } - } + int gapAddress; + int matchingGaps = 0; + for (auto &gap : gaps) + { + if (gap.second >= routineSize) + { + matchingGaps++; + gapAddress = gap.first; + } + } - if (matchingGaps == 1) - { - // Routine can only be placed in this particular gap - do so + if (matchingGaps == 1) + { + // Routine can only be placed in this particular gap - do so - gaps[gapAddress] -= routineSize; - int targetAddr = gapAddress + gaps[gapAddress]; - fixedRoutines[targetAddr] = floatingRoutines.back(); + gaps[gapAddress] -= routineSize; + int targetAddr = gapAddress + gaps[gapAddress]; + fixedRoutines[targetAddr] = floatingRoutines.back(); - std::cout << "forced reducing gap $" << std::hex << gapAddress << std::dec << " to size " << - gaps[gapAddress] << std::endl; + logOutput << "forced reducing gap $" << std::hex << gapAddress << std::dec << " to size " << + gaps[gapAddress] << "\n"; - spacing.resize(GLOBAL_maxFileNameLen + 4 - floatingRoutines.back()->fileName.length(), ' '); - std::cout << " $" << std::hex << targetAddr << std::dec << ": " << - floatingRoutines.back()->fileName << spacing << "size: " << - floatingRoutines.back()->codeLength << std::endl; + spacing.resize(GLOBAL_maxFileNameLen + 4 - floatingRoutines.back()->fileName.length(), ' '); + logOutput << " $" << std::hex << targetAddr << std::dec << ": " << + floatingRoutines.back()->fileName << spacing << "size: " << + floatingRoutines.back()->codeLength << "\n"; - floatingRoutines.pop_back(); - if (gaps[gapAddress] == 0) gaps.erase(gapAddress); + floatingRoutines.pop_back(); + if (gaps[gapAddress] == 0) gaps.erase(gapAddress); - repeat = true; - } - } + repeat = true; + } + } } -void BinningProblem::removeUselessGaps() +void BinningProblem::removeUselessGaps(DualStream &logOutput) { - // Get the size of the smallest floating routine, - // remove all the gaps which are smaller in size + // Get the size of the smallest floating routine, + // remove all the gaps which are smaller in size - int minUsefulSize = floatingRoutines[0]->codeLength; + int minUsefulSize = floatingRoutines[0]->codeLength; - bool repeat = true; - while (repeat) - { - repeat = false; - for (auto &gap : gaps) - { - if (gap.second < minUsefulSize) - { - std::cout << "dropping gap: $" << std::hex << gap.first << std::dec << " (size: " << gap.second << ")" << std::endl; - gaps.erase(gap.first); - repeat = true; - break; - } - } - } + bool repeat = true; + while (repeat) + { + repeat = false; + for (auto &gap : gaps) + { + if (gap.second < minUsefulSize) + { + logOutput << "dropping gap: $" << std::hex << gap.first << std::dec << " (size: " << gap.second << ")" << "\n"; + gaps.erase(gap.first); + repeat = true; + break; + } + } + } } void BinningProblem::sortFloatingRoutinesBySize() { - // Sort the unallocated routines by size, starting from the smallest one + // Sort the unallocated routines by size, starting from the smallest one - auto compare = [](const SourceFile *a, const SourceFile *b) -> bool { return a->codeLength < b->codeLength; }; - std::sort (floatingRoutines.begin(), floatingRoutines.end(), compare); + auto compare = [](const SourceFile *a, const SourceFile *b) -> bool { return a->codeLength < b->codeLength; }; + std::sort (floatingRoutines.begin(), floatingRoutines.end(), compare); } // @@ -800,184 +849,201 @@ void BinningProblem::sortFloatingRoutinesBySize() void Solver::run() { - problem.sortFloatingRoutinesBySize(); // just to be extra sure + // Prepare the log file - while (!problem.gaps.empty() && !problem.floatingRoutines.empty()) - { - problem.performObviousSteps(); - problem.removeUselessGaps(); + const std::string logFileName = CMD_tmpDir + DIR_SEPARATOR + CMD_segName + "_solver.log"; + unlink(logFileName.c_str()); + logFile.open(logFileName, std::fstream::out | std::fstream::trunc); - if (problem.gaps.empty() || problem.floatingRoutines.empty()) break; + // Sort the floating routines, just to be extra sure - int gapAddr = selectGapToFill(); + problem.sortFloatingRoutinesBySize(); - std::cout << "selected gap: " << "$" << std::hex << gapAddr << std::dec << " (size: " << problem.gaps[gapAddr] << ")" << std::endl; + // Run the solver until all is done - std::list partialSolution; - findPartialSolution(problem.gaps[gapAddr], partialSolution); - problem.fillGap(gapAddr, partialSolution); - } + while (!problem.gaps.empty() && !problem.floatingRoutines.empty()) + { + problem.performObviousSteps(logOutput); + problem.removeUselessGaps(logOutput); - if (problem.isSolved()) - { - std::cout << std::endl << "all the routines sucessfully placed" << std::endl << std::endl; - } + if (problem.gaps.empty() || problem.floatingRoutines.empty()) break; + + int gapAddr = selectGapToFill(); + + logOutput << "selected gap: $" << std::hex << gapAddr << std::dec << " (size: " << problem.gaps[gapAddr] << ")" << "\n"; + + std::list partialSolution; + findPartialSolution(problem.gaps[gapAddr], partialSolution); + problem.fillGap(logOutput, gapAddr, partialSolution); + } + + // Print out the result + + if (problem.isSolved()) + { + logOutput << "\n" << "all the routines sucessfully placed" << "\n\n"; + } + + // Close the log file + + if (!logFile.good()) ERROR(std::string("error writing log file '") + logFileName + "'"); + logFile.close(); } int Solver::selectGapToFill() { - // Find the smallest gap to fill-in + // Find the smallest gap to fill-in - int gapAddr = -1; - int gapSize = -1; + int gapAddr = -1; + int gapSize = -1; - for (auto &gap : problem.gaps) - { - if (gapSize < 0 || gap.second < gapSize) - { - gapAddr = gap.first; - gapSize = gap.second; - } - } + for (auto &gap : problem.gaps) + { + if (gapSize < 0 || gap.second < gapSize) + { + gapAddr = gap.first; + gapSize = gap.second; + } + } - return gapAddr; + return gapAddr; } int KS(const std::vector &routines, - std::vector> &cacheV, // value cache - std::vector>> &cacheS, // partial solution cache - int n, int C, - std::list &solution) // sequence of decisions for each routine, has to be empty when calling + std::vector> &cacheV, // value cache + std::vector>> &cacheS, // partial solution cache + int n, int C, + std::list &solution) // sequence of decisions for each routine, has to be empty when calling { - // This routine solves a knapsack problem using a dynamic programming + // This routine solves a knapsack problem using a dynamic programming - // XXX Possible efficiency improvement for the future: try to consider more than one gap at once, - // this will need a serious rework of the dynamic cache handling and will probably hurt the performance + // XXX Possible efficiency improvement for the future: try to consider more than one gap at once, + // this will need a serious rework of the dynamic cache handling and will probably hurt the performance - if (n == 0) - { - // No more routines to take the decision... - return 0; - } + if (n == 0) + { + // No more routines to take the decision... + return 0; + } - if (C == 0) - { - // We have no capacity left - decisions for all the routines left should be not to take them - solution.resize(n, false); - return 0; - } + if (C == 0) + { + // We have no capacity left - decisions for all the routines left should be not to take them + solution.resize(n, false); + return 0; + } - auto &cachedV = cacheV[n - 1][C - 1]; - auto &cachedS = cacheS[n - 1][C - 1]; - if (cachedV >= 0) - { - // We already hold the solution in out cache - return it - solution = cachedS; - return cachedV; - } + auto &cachedV = cacheV[n - 1][C - 1]; + auto &cachedS = cacheS[n - 1][C - 1]; + if (cachedV >= 0) + { + // We already hold the solution in out cache - return it + solution = cachedS; + return cachedV; + } - auto &codeSize = routines[n - 1]->codeLength; - if (codeSize > C) - { - // We can't take this routine, it's too large + auto &codeSize = routines[n - 1]->codeLength; + if (codeSize > C) + { + // We can't take this routine, it's too large - cachedV = KS(routines, cacheV, cacheS, n - 1, C, solution); - solution.push_back(false); - cachedS = solution; + cachedV = KS(routines, cacheV, cacheS, n - 1, C, solution); + solution.push_back(false); + cachedS = solution; - return cachedV; - } + return cachedV; + } - // Note: it it seems equally good to take this routine, or not - take it! - // Evaluation starts from the largest routines, and we should prefer to leave - // a larger number of smaller routines - as this gives more possibilities - // while optimizing the usage of further gaps + // Note: it it seems equally good to take this routine, or not - take it! + // Evaluation starts from the largest routines, and we should prefer to leave + // a larger number of smaller routines - as this gives more possibilities + // while optimizing the usage of further gaps - std::list solution1; - int val1 = KS(routines, cacheV, cacheS, n - 1, C - codeSize, solution1) + codeSize; // take + std::list solution1; + int val1 = KS(routines, cacheV, cacheS, n - 1, C - codeSize, solution1) + codeSize; // take - if (val1 == C) - { - // By taking this routine we are filling all the space - contrary to the classic - // knapsack problem, this is an optimal solution for us, don't waste time calculating - // the others + if (val1 == C) + { + // By taking this routine we are filling all the space - contrary to the classic + // knapsack problem, this is an optimal solution for us, don't waste time calculating + // the others - cachedV = val1; - solution = solution1; - solution.push_back(true); - cachedS = solution; - return cachedV; - } + cachedV = val1; + solution = solution1; + solution.push_back(true); + cachedS = solution; + return cachedV; + } - std::list solution2; - int val2 = KS(routines, cacheV, cacheS, n - 1, C, solution2); // don't take + std::list solution2; + int val2 = KS(routines, cacheV, cacheS, n - 1, C, solution2); // don't take - if (val1 >= val2) - { - // It's better to take this particular routine + if (val1 >= val2) + { + // It's better to take this particular routine - cachedV = val1; - solution = solution1; - solution.push_back(true); - } - else - { - // It's better not to take this particular routine + cachedV = val1; + solution = solution1; + solution.push_back(true); + } + else + { + // It's better not to take this particular routine - cachedV = val2; - solution = solution2; - solution.push_back(false); - } + cachedV = val2; + solution = solution2; + solution.push_back(false); + } - cachedS = solution; - return cachedV; + cachedS = solution; + return cachedV; }; void Solver::findPartialSolution(int gapSize, std::list &partialSolution) { - // First filter out available routines, take only the ones not larger than our gap + // First filter out available routines, take only the ones not larger than our gap std::vector routines; - routines.clear(); - for (auto &routine : problem.floatingRoutines) - { - if (routine->codeLength <= gapSize) - { - routines.push_back(routine); - } - else break; // 'floatingRoutines' should be kept sorted - } + routines.clear(); + for (auto &routine : problem.floatingRoutines) + { + if (routine->codeLength <= gapSize) + { + routines.push_back(routine); + } + else break; // 'floatingRoutines' should be kept sorted + } - // Prepare value cache + // Prepare value cache - std::vector> cacheV; - cacheV.resize(routines.size()); - for (auto &cacheRow : cacheV) cacheRow.resize(gapSize, -1); + std::vector> cacheV; + cacheV.resize(routines.size()); + for (auto &cacheRow : cacheV) cacheRow.resize(gapSize, -1); - // Prepare partial solution cache - std::vector>> cacheS; - cacheS.resize(routines.size()); - for (auto &cacheRow : cacheS) cacheRow.resize(gapSize); + // Prepare partial solution cache + std::vector>> cacheS; + cacheS.resize(routines.size()); + for (auto &cacheRow : cacheS) cacheRow.resize(gapSize); - // Calculate solution + // Calculate solution - std::list solution; - KS(routines, cacheV, cacheS, routines.size(), gapSize, solution); + std::list solution; + KS(routines, cacheV, cacheS, routines.size(), gapSize, solution); - if (routines.size() != solution.size()) bailOut(std::string("internal error line ") + std::to_string(__LINE__)); + if (routines.size() != solution.size()) ERROR(std::string("internal error line ") + std::to_string(__LINE__)); - // Return the solution upstream + // Return the solution upstream - while (!routines.empty()) - { - if (solution.back() != false) - { - partialSolution.push_front(routines.back()); - } + while (!routines.empty()) + { + if (solution.back() != false) + { + partialSolution.push_front(routines.back()); + } - routines.pop_back(); - solution.pop_back(); - } + routines.pop_back(); + solution.pop_back(); + } - return; + return; } From 49e8b75b855c3c71511475f7b7745dec86831cef Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Tue, 10 Sep 2019 18:28:30 +0200 Subject: [PATCH 9/9] explained all similarities >3, some minor cleanups --- c64/aliases/,aliases_ram_lowmem.s | 2 +- c64/kernal/memtop.s | 8 ++++---- c64/kernal/ramtas.s | 8 ++++---- src/build_segment.cc | 14 +++++++++++--- strings/0020BDFF | 4 ++++ strings/0020BDFF20 | 3 +++ strings/00857B60 | 3 +++ strings/00DD0910 | 7 +++++++ strings/00DD09108D00DD | 5 +++++ strings/00DD29DF8D00DD | 6 ++++++ strings/00DD29F78D00DD | 6 ++++++ strings/00DD60AD00DD0910 | 6 ++++++ strings/01857AA5 | 3 +++ strings/02186020 | 4 ++++ strings/034C28 | 3 +++ strings/034CE1 | 3 +++ strings/0DDC68A868AA6840 | 7 +++++++ strings/1860AD00DD | 3 +++ strings/290FF023 | 3 +++ strings/29DF8D00DD60 | 5 +++++ strings/3020D2FF68 | 3 +++ ...F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 | 6 ++++++ strings/60A000A2 | 3 +++ strings/60AD00DD09208D00DD | 7 +++++++ strings/6900852E | 5 +++++ strings/7060A5 | 3 +++ strings/85D4A922 | 3 +++ strings/8D00DD60AD00DD | 5 +++++ strings/8D00DD60AD00DD29 | 5 +++++ strings/8D850260 | 5 +++++ strings/A8AD0002 | 3 +++ strings/A9006020 | 3 +++ strings/AD00DD29 | 7 +++++++ strings/AD00DD29F78D00DD | 6 ++++++ strings/AD00DD29F78D00DD60 | 6 ++++++ strings/C3C2CD3830 | 15 +++++++++++++++ strings/C8B17A | 4 ++++ strings/C922D00B | 3 +++ strings/DF8D00DD60AD00DD09208D00DD | 7 +++++++ strings/E6C90DD0 | 3 +++ strings/EF8D00DD | 5 +++++ strings/EF8D00DD60 | 6 ++++++ strings/F6A5BA20 | 3 +++ strings/FD4C15FD4C1AFD4C | 1 + 44 files changed, 208 insertions(+), 12 deletions(-) create mode 100644 strings/0020BDFF create mode 100644 strings/0020BDFF20 create mode 100644 strings/00857B60 create mode 100644 strings/00DD0910 create mode 100644 strings/00DD09108D00DD create mode 100644 strings/00DD29DF8D00DD create mode 100644 strings/00DD29F78D00DD create mode 100644 strings/00DD60AD00DD0910 create mode 100644 strings/01857AA5 create mode 100644 strings/02186020 create mode 100644 strings/034C28 create mode 100644 strings/034CE1 create mode 100644 strings/0DDC68A868AA6840 create mode 100644 strings/1860AD00DD create mode 100644 strings/290FF023 create mode 100644 strings/29DF8D00DD60 create mode 100644 strings/3020D2FF68 create mode 100644 strings/31EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 create mode 100644 strings/60A000A2 create mode 100644 strings/60AD00DD09208D00DD create mode 100644 strings/6900852E create mode 100644 strings/7060A5 create mode 100644 strings/85D4A922 create mode 100644 strings/8D00DD60AD00DD create mode 100644 strings/8D00DD60AD00DD29 create mode 100644 strings/8D850260 create mode 100644 strings/A8AD0002 create mode 100644 strings/A9006020 create mode 100644 strings/AD00DD29 create mode 100644 strings/AD00DD29F78D00DD create mode 100644 strings/AD00DD29F78D00DD60 create mode 100644 strings/C3C2CD3830 create mode 100644 strings/C8B17A create mode 100644 strings/C922D00B create mode 100644 strings/DF8D00DD60AD00DD09208D00DD create mode 100644 strings/E6C90DD0 create mode 100644 strings/EF8D00DD create mode 100644 strings/EF8D00DD60 create mode 100644 strings/F6A5BA20 create mode 100644 strings/FD4C15FD4C1AFD4C diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index f7dd4ea0..8a18c4af 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -159,7 +159,7 @@ .label SAT = $26D // $26D-$276, secondary addresses (table, 10 bytes) .label KEYD = $277 // $277-$280, keyboard buffer .label MEMSTR = $281 // $281-$282, start of BASIC memory - .label MEMEND = $283 // $283-$284, NOTE: Mapping the 64 erroneously has the hex as $282 (DEC is correct), name seems to be mistaken too + .label MEMSIZK = $283 // $283-$284, NOTE: Mapping the 64 erroneously has the hex as $282 (DEC is correct) .label TIMOUT = $285 // IEEE-488 timeout .label COLOR = $286 // current text foreground color .label GDCOL = $287 // color of character under cursor diff --git a/c64/kernal/memtop.s b/c64/kernal/memtop.s index 06995cf8..dd50497a 100644 --- a/c64/kernal/memtop.s +++ b/c64/kernal/memtop.s @@ -12,13 +12,13 @@ MEMTOP: bcc memtop_set - ldy MEMEND+1 - ldx MEMEND+0 + ldy MEMSIZK+1 + ldx MEMSIZK+0 rts memtop_set: - sty MEMEND+1 - stx MEMEND+0 + sty MEMSIZK+1 + stx MEMSIZK+0 rts diff --git a/c64/kernal/ramtas.s b/c64/kernal/ramtas.s index d7481427..e5feb561 100644 --- a/c64/kernal/ramtas.s +++ b/c64/kernal/ramtas.s @@ -61,14 +61,14 @@ ramtas_l2: ldx #>$0400 stx HIBASE - // Work out RAM size and put in MEMSTR and MEMEND + // Work out RAM size and put in MEMSTR and MEMSIZK // "Compute's Mapping the 64", p54 // http://unusedino.de/ec64/technical/project64/mapping_c64.html ldx #>$0800 stx MEMSTR+1 ldx #$00 stx MEMSTR+0 - stx MEMEND+0 + stx MEMSIZK+0 // Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF lda $8000 eor #$FF @@ -79,12 +79,12 @@ ramtas_l2: beq ramtas_32K_RAM sta $8000 ldx #$A0 - stx MEMEND+1 + stx MEMSIZK+1 jmp ramtas_RAM_sized ramtas_32K_RAM: sta $8000 // in case RAM is hiding beneath a ROM ldx #$80 - stx MEMEND+1 + stx MEMSIZK+1 // Fall through ramtas_RAM_sized: diff --git a/src/build_segment.cc b/src/build_segment.cc index 26667b1d..3453d458 100644 --- a/src/build_segment.cc +++ b/src/build_segment.cc @@ -316,7 +316,7 @@ void calcRoutineSizes() // during this pass, which would otherwise upset things later outFile << "\n" << ".segment " << CMD_segName << " [start=$100, min=$100, max=$FFFF]" << "\n"; - outFile << "#define BUILD_" << CMD_segName << "\n"; + outFile << "#define SEGMENT_" << CMD_segName << "\n"; for (const auto &sourceFile : GLOBAL_sourceFiles) { @@ -516,7 +516,7 @@ void compileSegment() ", max=$" << std::hex << CMD_hiAddress << ", outBin=\"" << CMD_outFile << "\", fill]" << "\n"; - outFile << "#define BUILD_" << CMD_segName << "\n"; + outFile << "#define SEGMENT_" << CMD_segName << "\n"; // Write files which only contain definitions (no routines) @@ -609,6 +609,7 @@ SourceFile::SourceFile(const std::string &fileName, const std::string &dirName) inFile.seekg(0); inFile.read(&content[0], fileLength); if (!inFile.good()) ERROR("error reading file content"); + if (content.back() != '\n') content.push_back('\n'); inFile.close(); @@ -915,7 +916,14 @@ int KS(const std::vector &routines, int n, int C, std::list &solution) // sequence of decisions for each routine, has to be empty when calling { - // This routine solves a knapsack problem using a dynamic programming + // This routine solves a knapsack problem using a dynamic programming. + // + // In short: 'routines' contains a list of routines that can potentially be placed in the gap of size C. + // We start from index n (the highest one), referencing the last routine from the list (the largest one, + // as the list is sorted). Our goal: by recursively searching the tree of all possible solutions + // (solution = a sequence of decisions, each telling whether to take the routine or not) find the one + // that fills the gap in the most complete way. Additional cache greatly speeds up the algorithm. + // See the comments below to fully understand how it works. // XXX Possible efficiency improvement for the future: try to consider more than one gap at once, // this will need a serious rework of the dynamic cache handling and will probably hurt the performance diff --git a/strings/0020BDFF b/strings/0020BDFF new file mode 100644 index 00000000..cef2783f --- /dev/null +++ b/strings/0020BDFF @@ -0,0 +1,4 @@ +$00 + JSR $FFBD (SETNAM routine jumptable address) + +Value + a jump to a documented location - trivial, not copyrightable. + diff --git a/strings/0020BDFF20 b/strings/0020BDFF20 new file mode 100644 index 00000000..cc3c9e42 --- /dev/null +++ b/strings/0020BDFF20 @@ -0,0 +1,3 @@ +$00 + JSR $FFBD (SETNAM routine jumptable address) + JSR (address does not match) + +Value + a jump to a documented location + beginning of the next instruction - trivial, not copyrightable. diff --git a/strings/00857B60 b/strings/00857B60 new file mode 100644 index 00000000..3fc82b38 --- /dev/null +++ b/strings/00857B60 @@ -0,0 +1,3 @@ +$00 + STA $7B + RTS + +Routine ending, storing a value in a documented zeropage location - trivial, not copyrightable. diff --git a/strings/00DD0910 b/strings/00DD0910 new file mode 100644 index 00000000..2ad4a1a8 --- /dev/null +++ b/strings/00DD0910 @@ -0,0 +1,7 @@ +$DD00 + ORA #$10 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. What's more - this is only an instruction and a half - trivial, not copyrightable. + + diff --git a/strings/00DD09108D00DD b/strings/00DD09108D00DD new file mode 100644 index 00000000..3a01f362 --- /dev/null +++ b/strings/00DD09108D00DD @@ -0,0 +1,5 @@ +$DD00 + ORA #$10 + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/00DD29DF8D00DD b/strings/00DD29DF8D00DD new file mode 100644 index 00000000..c56653eb --- /dev/null +++ b/strings/00DD29DF8D00DD @@ -0,0 +1,6 @@ +$DD00 + AND #$DF + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. + diff --git a/strings/00DD29F78D00DD b/strings/00DD29F78D00DD new file mode 100644 index 00000000..e0d8d6da --- /dev/null +++ b/strings/00DD29F78D00DD @@ -0,0 +1,6 @@ +$DD00 + AND #$F7 + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. + diff --git a/strings/00DD60AD00DD0910 b/strings/00DD60AD00DD0910 new file mode 100644 index 00000000..775584e1 --- /dev/null +++ b/strings/00DD60AD00DD0910 @@ -0,0 +1,6 @@ +$DD00 + RTS + LDA $DD00 + ORA #$10 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. + diff --git a/strings/01857AA5 b/strings/01857AA5 new file mode 100644 index 00000000..6fbf6ebc --- /dev/null +++ b/strings/01857AA5 @@ -0,0 +1,3 @@ +$01 + STA $7A + LDA (address does not match) + +Instruction (storing value on zero page) + some parts - trivial, not copyrightable. diff --git a/strings/02186020 b/strings/02186020 new file mode 100644 index 00000000..d952091b --- /dev/null +++ b/strings/02186020 @@ -0,0 +1,4 @@ +$02 + CLC + RTS + JSR (address does not match) + +Subroutine ending by setting 'carry' flag (standard way to indicate failure) placed +just before another one, starting with a jump (to a different address) - not creative, not copyrightable. diff --git a/strings/034C28 b/strings/034C28 new file mode 100644 index 00000000..6cbdc7e8 --- /dev/null +++ b/strings/034C28 @@ -0,0 +1,3 @@ +$03 + JMP (address matches only partially) + +Not even a full instruction - not copyrightable. diff --git a/strings/034CE1 b/strings/034CE1 new file mode 100644 index 00000000..fe09e73a --- /dev/null +++ b/strings/034CE1 @@ -0,0 +1,3 @@ +$03 + JMP (address match only partially) + +Not even a full instruction - not copyrightable diff --git a/strings/0DDC68A868AA6840 b/strings/0DDC68A868AA6840 new file mode 100644 index 00000000..d5a75384 --- /dev/null +++ b/strings/0DDC68A868AA6840 @@ -0,0 +1,7 @@ +$DC0D + PLA + TAY + PLA + TAX + PLA + RTI + +Some access to a docummented hardware register (but details differ) + return from the interrupt in a standard 6502 way - see for example here: + +http://6502.org/tutorials/register_preservation.html + +Not copyrightable. diff --git a/strings/1860AD00DD b/strings/1860AD00DD new file mode 100644 index 00000000..acd02296 --- /dev/null +++ b/strings/1860AD00DD @@ -0,0 +1,3 @@ +CLC + RTS + LDA $DD00 + +End of a routine setting carry flag as a result (probably to indicate error) followed by another, which starts by reading a documented hardware register. Not creative (especially that routine location is determineed by algorithm in our case) - not copyrightable. diff --git a/strings/290FF023 b/strings/290FF023 new file mode 100644 index 00000000..97fb1d77 --- /dev/null +++ b/strings/290FF023 @@ -0,0 +1,3 @@ +AND #$0F + BEQ (offset match) + +Check whether the lowest nibble of a byte is zero or not - trivial, not copyrightable. diff --git a/strings/29DF8D00DD60 b/strings/29DF8D00DD60 new file mode 100644 index 00000000..3a1307ee --- /dev/null +++ b/strings/29DF8D00DD60 @@ -0,0 +1,5 @@ +AND #$DF + STA $DD00 + RTS + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/3020D2FF68 b/strings/3020D2FF68 new file mode 100644 index 00000000..0170bc30 --- /dev/null +++ b/strings/3020D2FF68 @@ -0,0 +1,3 @@ +$30 + JSR $FFD2 + PLA + +A byte, call to a documented routine (CHROUT), restoring the register value - trivial, not copyyrightable. diff --git a/strings/31EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 b/strings/31EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 new file mode 100644 index 00000000..4abe259c --- /dev/null +++ b/strings/31EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 @@ -0,0 +1,6 @@ +a list of vectors to be copied starting from $0314 + +Values of the vectors are already present in many autostart software - as it often overrides them, +sometimes changing one to trigger autostart (one of the possible techniques). We have to use the same +vector values to be compatible (in fact, it even complicates our implementation) - see *.interop files +for more details. diff --git a/strings/60A000A2 b/strings/60A000A2 new file mode 100644 index 00000000..905ee905 --- /dev/null +++ b/strings/60A000A2 @@ -0,0 +1,3 @@ +RTS (end of previous routine) + LDY #$00 + LDX (value does not match) + +Routine starts by loading 0 to Y and something (here values differ) to X - trivial, not copyrightable. diff --git a/strings/60AD00DD09208D00DD b/strings/60AD00DD09208D00DD new file mode 100644 index 00000000..2768b68a --- /dev/null +++ b/strings/60AD00DD09208D00DD @@ -0,0 +1,7 @@ +RTS + LDA $DD00 + ORA #$20 + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. + + diff --git a/strings/6900852E b/strings/6900852E new file mode 100644 index 00000000..fd5b1476 --- /dev/null +++ b/strings/6900852E @@ -0,0 +1,5 @@ +ADC #$00 + STA $2E ($2D-$2E is VARTAB, end of BASIC code) + +Part of code incrementing a documented 16-bit value - trivial, not copyrightable. + + diff --git a/strings/7060A5 b/strings/7060A5 new file mode 100644 index 00000000..622b65b2 --- /dev/null +++ b/strings/7060A5 @@ -0,0 +1,3 @@ +$70 + RTS + LDA (zeropage address, but does not match) + +One instruction (and just a one-byte instruction) + some parts - not copyrightable. diff --git a/strings/85D4A922 b/strings/85D4A922 new file mode 100644 index 00000000..c36927d4 --- /dev/null +++ b/strings/85D4A922 @@ -0,0 +1,3 @@ +STA $D4 + LDA #$22 + +Storing value to a well-known zeropage variable + loading another to the accumulator - not crative, not copyrightable. diff --git a/strings/8D00DD60AD00DD b/strings/8D00DD60AD00DD new file mode 100644 index 00000000..e1f405dc --- /dev/null +++ b/strings/8D00DD60AD00DD @@ -0,0 +1,5 @@ +STA $DD00 + RTS + LDA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/8D00DD60AD00DD29 b/strings/8D00DD60AD00DD29 new file mode 100644 index 00000000..3cbc6b23 --- /dev/null +++ b/strings/8D00DD60AD00DD29 @@ -0,0 +1,5 @@ +STA $DD00 + RTS + LDA $DD00 + AND (value does not match) + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/8D850260 b/strings/8D850260 new file mode 100644 index 00000000..7886e29c --- /dev/null +++ b/strings/8D850260 @@ -0,0 +1,5 @@ +STA $0285 (TIMOUT variable) + RTS + +SETTMO routine. There really is just one sane way to implement +a subroutine storing accumulator in a fixed memory location. +Not creative - not copyrightable. diff --git a/strings/A8AD0002 b/strings/A8AD0002 new file mode 100644 index 00000000..da514732 --- /dev/null +++ b/strings/A8AD0002 @@ -0,0 +1,3 @@ +$A8 + LDA $0200 + +Instruction (accessing BASIC instruction buffer) + some part. Trivial, not copyrightable. diff --git a/strings/A9006020 b/strings/A9006020 new file mode 100644 index 00000000..d8fdedb9 --- /dev/null +++ b/strings/A9006020 @@ -0,0 +1,3 @@ +LDA #$00 + RTS + JSR (address does not match) + +End of a rutine which returns 0 in accumulator, another one starts with a jump (but to a different address) - trivial, not copyrightable. diff --git a/strings/AD00DD29 b/strings/AD00DD29 new file mode 100644 index 00000000..264e0626 --- /dev/null +++ b/strings/AD00DD29 @@ -0,0 +1,7 @@ +LDA $DD00 + AND (value does not match) + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. Also - instruction and a half is trivial - not copyrightable. + + diff --git a/strings/AD00DD29F78D00DD b/strings/AD00DD29F78D00DD new file mode 100644 index 00000000..82f4c3e6 --- /dev/null +++ b/strings/AD00DD29F78D00DD @@ -0,0 +1,6 @@ +LDA $DD00 + AND #$F7 + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. + diff --git a/strings/AD00DD29F78D00DD60 b/strings/AD00DD29F78D00DD60 new file mode 100644 index 00000000..3746c1e9 --- /dev/null +++ b/strings/AD00DD29F78D00DD60 @@ -0,0 +1,6 @@ +LDA $DD00 + AND #$F7 + STA $DD00 + RTS + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. + + diff --git a/strings/C3C2CD3830 b/strings/C3C2CD3830 new file mode 100644 index 00000000..322b1708 --- /dev/null +++ b/strings/C3C2CD3830 @@ -0,0 +1,15 @@ +CBM80 PETSCII string + +CBM80 is the string used to compare with the signature block of +a cartridge. It is required for interoperability with C64 cartridges, +and the requirement for this string is explicit, and is well documented, +including the string itself, in many places, such as: + +http://mirror.thelifeofkenneth.com/sites/remotecpu.com/Commodore/Reference%20Material/Manuals/Hardware%20Manuals/Datel%20Eprommer64%20Instruction%20Manual.pdf + +Indeed, the C64 Programmer's Reference Guide describes it on p263. + +Since Commodore instructed cartridge developers to include the string +in cartridges, it cannot be held to be a violation of copyrights, +even if it were able to be copyrighted, which we do not accept on grounds +including that it is a list of facts (published by Commodore themselves) diff --git a/strings/C8B17A b/strings/C8B17A new file mode 100644 index 00000000..4a5c8f24 --- /dev/null +++ b/strings/C8B17A @@ -0,0 +1,4 @@ +INY + LDA ($7A),Y + +Part of the loop reading BASIC statement, loops reading data block pointed by vector +always look like this on 6502, as LDA (...),X does not exists on this CPU. Trivial - not copyrightable. diff --git a/strings/C922D00B b/strings/C922D00B new file mode 100644 index 00000000..a97c7d05 --- /dev/null +++ b/strings/C922D00B @@ -0,0 +1,3 @@ +CMP #$22 + BNE (offset matches) + +Comparing register to value, would be a single instruction on other architectures. Trivial - not copyrightable. diff --git a/strings/DF8D00DD60AD00DD09208D00DD b/strings/DF8D00DD60AD00DD09208D00DD new file mode 100644 index 00000000..9bdd8fc9 --- /dev/null +++ b/strings/DF8D00DD60AD00DD09208D00DD @@ -0,0 +1,7 @@ +$DF + STA $DD00 + RTS + LDA $DD00 + ORA #$20 + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. + + diff --git a/strings/E6C90DD0 b/strings/E6C90DD0 new file mode 100644 index 00000000..6bd55640 --- /dev/null +++ b/strings/E6C90DD0 @@ -0,0 +1,3 @@ +$E6 + CMP #$0D + BNE (offset does not match) + +Instruction + some parts. Not copyyrightable. diff --git a/strings/EF8D00DD b/strings/EF8D00DD new file mode 100644 index 00000000..3f1acd45 --- /dev/null +++ b/strings/EF8D00DD @@ -0,0 +1,5 @@ +$EF + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/EF8D00DD60 b/strings/EF8D00DD60 new file mode 100644 index 00000000..2741c33b --- /dev/null +++ b/strings/EF8D00DD60 @@ -0,0 +1,6 @@ +$EF + STA $DD00 + RTS + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. + diff --git a/strings/F6A5BA20 b/strings/F6A5BA20 new file mode 100644 index 00000000..a44542e8 --- /dev/null +++ b/strings/F6A5BA20 @@ -0,0 +1,3 @@ +$F6 + LDA $BA + JSR (address does not match) + +One instruction (reading a well-known zeropage value) + some parts. Not copyrightable. diff --git a/strings/FD4C15FD4C1AFD4C b/strings/FD4C15FD4C1AFD4C new file mode 100644 index 00000000..93764d3f --- /dev/null +++ b/strings/FD4C15FD4C1AFD4C @@ -0,0 +1 @@ +This is a part of Kernal jumptable - series of jumps, sometimes to the well known addreses (or through documented vectors). No business logic, part of the Kernal API itself (has to be as it is to maintain compatibility) - not copyrightable.