?login_element?

Subversion Repositories NedoOS

Rev

Rev 1448 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;
  2. ;65C02 emulator on a Z80
  3. ;by James Smith (UK), 2008
  4. ;
  5.         DEVICE ZXSPECTRUM1024
  6.         include "../_sdk/sys_h.asm"
  7.  
  8. ;UNEXPANDED VIC20
  9.  
  10. ;section below defines macros
  11.  
  12. ;V1.01 - 2T off decoding loop and 4T off BRAnch instructions.
  13. ;V1.02 - 4T off ZP,X ; ZP,Y code
  14. ;V1.03 - fixed JSR (a,X) instruction. 11T off INX/DEX/INY/DEY instructions
  15. ;V1.04 - fixed PLP (Z flag lost). Modified TRB (CPL before AND now)
  16. ;v1.05 - redesigned ADC and SBC instructions to cope with BCD more quickly
  17. ;v1.06 - UK101 related
  18. ;v1.10 - improved 6502 core - using half of DR BEEP method
  19. ;v1.11 - UK101 related
  20. ;v1.12 - better way of setting Z flag - improved TRB,TSB,BIT and PHP instructions
  21. ;v1.13 - better way of setting V flag - improved ADC,SBC instructions
  22. ;v1.14 - fixed (indirect,X) addressing mode - missed out LD L,A after ADD A,L instruction
  23. ;v1.15 - 3T off BVC instruction. Improved keyscan routine - quicker and supports CTRL+C
  24. ;v1.16 - 7T off absolute,X ; abs,Y ; (ind),Y routines
  25. ;v1.17 - 4T off (indirect,X). Fix from v1.14 has been optimised.
  26. ;v1.18 - UK101 related
  27. ;v1.19 - 2T off PHP, 12T off RTI, 13T off PLP instructions
  28. ;v1.20 - 4T off abs,X ; abs,Y ; (ind),Y routines
  29. ;v1.21 - bug fixed in new PHP. 4T off (indirect,X). Illegal opcodes reduced to 3 bytes long
  30. ;v1.22 - branch instructions recoded. 7T/10T off each instruction
  31. ;v1.23 - 7T off JSR, 2T off BRK instructions
  32. ;v1.24 - UK101 related
  33. ;v1.25 - change refs from vYreg to IYH - effectively a test to see if it works
  34. ;v1.26 - change refs from vXreg to IYL. 4T off LDX/LDY instructions
  35.  
  36. ;v1.41 - implemented $9120 (write), keyboard routines. Fixed bug in row 16+ of screendraw
  37. ;v1.42 - implemented F1/3/5/7 keys, cursor keys, RUNSTOP, left arrow, VIC table, Column width register
  38. ;        however cursor keys now stop normal SHIFT+5 to +8 which means you can't do '(' !
  39. ;V1.43 - 3K expanded RAM added. Charmap made read only now.
  40. ;v1.44 - 4T off TSX and TXS. Changes to code to make it more address independent.
  41. ;v1.45 - NMI implemented. Pound sign key defined. Charset pointer ($9005) implemented. Cursor keys removed.
  42. ;        tried to implement VIA1 IFR and IER - still no RUN/STOP+RESTORE break key.
  43. ;V1.50 - New memory maps specified - 8K VIC RAM now contiguous. Assembly less sensitive on location address
  44. ;v1.51 - New way of accessing VIC/VIA I/O addresses
  45. ;v1.52 - Fixed JR error in TRB,TSB. 2T off PLP, 4T off PHP instructions. Removed need for FFpage constant.
  46. ;v1.53 - Row depth register implemented. False border implemented to give indication of VIC screen size.
  47. ;v1.54 - Colour RAM implemented. Invert screen bit and background colour of $900F now implemented.
  48. ;v1.55 - redesigned colour ram/invert implementation. Now trap updates to colour ram and update colours
  49. ;        seperately from screen ram. Invert now done in ATTR stage rather than screen ram stage.
  50. ;        RUN/STOP+RESTORE now works as $912F and $911F are write mirrors of $9121 and $9111 and need to work.
  51. ;v1.56 - put bright colours into colour mapping table. Supported wraparound when chargen points to 7168
  52. ;        (codes 128+ wrap into ROM at $8000). Fixed bug in $9003 routine. Changed SUB $CE to SUB colourram.
  53. ;v1.57 - change to background colour now forces whole screen attr refresh. Unneeded SUB $F0 removed from $9005
  54. ;v1.58 - added support for joystick (via Kempston). $9003 routine modified to refresh screen when row depth
  55. ;        changed. Attribute refresh routines also take into account row depth now (didn't before). All access
  56. ;        for reading to VIA/VIC is via a jump table
  57. ;v1.59 - 10T off write traps and a further 11T off screenwrite. RUN/STOP key implemented.
  58. ;        Discovered that v1.58/9 are slower as VIC is always checking VIA1 911F (tape sense in IRQ routine - $EAEF)
  59. ;v1.60 - another core change. This time to memory read/write routines. 4T off each memory read/write (not M1 fetch)
  60. ;        also some changes to I/O routines as they have to set H on exit rather than A. FFrealpage re-implemented.
  61. ;V1.61 - Psuedo double-height chars routine implemented. Right joystick routine fixed.
  62. ;        9T off VICout routine as quicker method than PUSH BC/POP IX is used
  63. ;        Rowtable used in screenwrite routine - over 10T quicker now
  64. ;        Minor speed improvements in ATTR and VICout routines.
  65. ;v1.62 - Improvements to double-height routine made. Screenwrite DJNZ loop expanded out for increased speed.
  66. ;        $9004 (and $9003 bit 7) raster counter implemented. Implemented CBM key (SYM+C)
  67. ;v1.63 - Implemented SOUND ($900A-$900D). VIA T1 lsb emulated for randomness by using Z80 R register
  68. ;v1.64 - Improved reset routine to reset VIC display. Fixed JR bug in $900F routine.
  69. ;        3T off RAMread_trap routine. Stopped VICborder from going bright.
  70. ;v1.65 - 6T off CLI/SEI/CLD/SED. Speed improvements in VIAout, VIA2B, rVICsoundA/B/C. Fixed bug in RAMread_trap
  71. ;        causing character set changes to fail.
  72. ;v1.66 - Faster attr4 routine. Added SYM+6 for CURSOR DOWN and SYM+8 for CURSOR RIGHT. SYM+4 is HOME.
  73. ;v1.67 - Fault in paging tables. Unallocated memory should point to $02 not $00 - otherwise it corrupts
  74. ;        page $FF (top of Kernal ROM). Also fixed character ROM pointers. RAMread_trap faster as IOread will never
  75. ;        straddle 2 pages, so safe to use 8-bit arithmetic.
  76. ;v1.68 - Major fault in Writescreen fixed! When non-double height chars were in use, IX wasn't being reset back to
  77. ;        normal effectively causing the routine to be run twice. LISTing a BASIC program is now 20% quicker!! Also
  78. ;        changed limits of column width to 31 columns (was 27). EI at start relocated after 6502 has been initialised.
  79. ;v1.69 - assembly listing tidied up. Routines re-organised (couldn't make it 256 bytes shorter). Other tables moved
  80. ;        in memory to fit. All tables moved to end of code for easier changing in the future. refreshattr, NMI and
  81. ;        IRQ routines modified to be position independent. Slightly faster NMI and IRQ routines.
  82. ;v1.70 - Core change. The addressing modes which fetch 2 bytes after opcode (eg: absolute,X) were translating DE twice.
  83. ;        Now DE is only retranslated if page boundary is crossed via the nextbyte2 routine. JSR + JMP also changed.
  84. ;v1.71 - Further core changes. Now nextbyte has also been changed. Unfortunately the main decode loop is 4T slower as
  85. ;        the translated address msb needs to be stored for use by nextbyte.
  86. ;v1.72 - 32T off PLP! 3T off BVC and BVS instructions. BIT #imm fixed as it should only modify Z flag. Attr5/6 modified
  87. ;        to handle BRIGHT bit correctly. VIC9002 modified to support colourRAM at either $9400 or $9600.
  88. ;v1.73 - Flaw in PLP fixed, but now it's only -15T off. JMP (addr) changed to use correct macros (readtrap). Core changes
  89. ;        of 1.70 and 1.71 have been changed. Getting the opcode and following byte or two should be treat as "M1"
  90. ;        fetches. These aren't trapped only translated, so the code therefore never needs to CALL RAMread_trap. The main
  91. ;        decoding loop is 4T faster (back to how it was).
  92. ;v1.74 - Back to v1.72 core, but with revised m1trap routine.
  93. ;v1.75 - Back to v1.73 core but with revised "nextbyte2" macro and faster m1trap routine. Fix for ROL A and ROR A.
  94. ;v1.76 - Re-org of 6502 routines - 768 bytes shorter. Fixes for JMP (A,X) and BRK included.
  95. ;v1.77 - Keyboard scan routine modified to exit quickly if no keys are pressed and other minor speed improvements.
  96. ;v1.80 - core verification with C64 utilities. Changes : 1) PLP forces bit 5 to 1. 2) PHP/BRK force B flag set during
  97. ;        push. D mode can now be set via PLP.
  98. ;v1.81 - speed improvements to BCS/CC/PL/MI/VS/VC/EQ/NE as full nextbyte macro is only needed when branch is required.
  99. ;        22T saved when condition isn't met.
  100. ;v1.82 - Speed up for Ind,Y; abs,X and abs,Y instructions. Improvement to ADC.
  101. ;        Changed RETI to RET in interrupt routine. Better 'illegal' routines.
  102. ;v1.83 - Improvements to graphics routines.  Faster attr routines as coltrans table is page aligned. Screen now
  103. ;        allowed to be 24 rows high. Screen memory now allowed to be moved, enabling expanded memory support.
  104. ;v1.86 - At least 10T off PHP, 2T off PLP. SP moved to non-contended RAM. Attr5/6 shorter and faster. RAMtrap moved
  105. ;        into screenwrite routine saving 6T when writing to screen. Changes to bit 7 of $9002 now force screen
  106. ;        memory to be recalculated - this fixes many bugs.
  107. ;v1.87 - 3T off RTI. 4T off PLP (except when using RTI). Rewritten joystick routines. Writescreen 8/16 row code (got rid
  108. ;        of jp to enddisplay2 and row counting code optimised - use ADD instead of SBC). Several VIC routines also
  109. ;        changed to cope with this.
  110. ;v1.88 - speed up in attr4
  111. ;v1.89 - fixed PLP (4T slower). RTI -6T. ADD and SBC ops are shorter and 3T faster when overflow set. Rewritten sound
  112. ;        routines. BRK 3T quicker, 1 byte shorter.
  113. ;v1.90 - routines modified to use real AF for 6502 A and F registers. AF' used by Z80 routines. Imm + ZP modes don't
  114. ;        corrupt Z80 A-reg or flags. TSB/TRB/BIT recoded. Bug in screenshow when rows (9003)=0 fixed. VIA/VIC
  115. ;        trap code quicker. NMI/IRQ code changed. Various memory sizes implemented.
  116.  
  117. ;#define DEFB .BYTE
  118. ;#define DW .WORD
  119. ;#define DEFM .TEXT
  120. ;#define ORG  .ORG
  121. ;#define EQU  .EQU
  122. ;#define equ  .EQU
  123. ;#define DB   .BYTE
  124. ;#define db   .BYTE
  125.  
  126. base            EQU $B400       ;THIS IS +512 FROM WHERE CODE STARTS!!
  127.  
  128. ZPrealpage      EQU $80
  129. SPrealpage      EQU $81
  130. FFrealpage      EQU $7F
  131. chargen         EQU $A000
  132. ScreenPage      EQU $9E
  133. colourram       EQU $B0
  134. ;page 1 must ALWAYS be after page 0!
  135.  
  136. M1page          EQU (base+$2900)/256    ;was $DB
  137. MRpage          EQU (base+$2A00)/256    ;was $DC ;read readdressing+1 for every HSB
  138. MWpage          EQU (base+$2B00)/256    ;was $DD ;write readdressing+1 for every HSB
  139. Oppage          EQU (base+$2800)/256    ;was $DA
  140. IM2page         EQU (base+$2600)/256    ;was $D8
  141. Safepage        EQU base+$1800
  142.         ;display "end=",end
  143.  
  144. ;all opcode routine addresses need to be
  145. ;defined before trying to assemble it
  146. ;otherwise the ORG base+x instructions won't make much sense
  147.  
  148. OP0     EQU base+$0     ;len=57
  149. OP1     EQU base+$1701  ;len=42
  150. OP2     EQU base+$1602  ;len=3
  151. OP3     EQU base+$1503  ;len=3
  152. OP4     EQU base+$1404  ;len=22
  153. OP5     EQU base+$1605  ;len=20
  154. OP6     EQU base+$1506  ;len=17
  155. OP7     EQU base+$1307  ;len=3
  156. OP8     EQU base+$1208  ;len=29
  157. OP9     EQU base+$1109  ;len=17
  158. OP10    EQU base+$130A  ;len=8
  159. OP11    EQU base+$100B  ;len=3
  160. OP12    EQU base+$F0C   ;len=37
  161. OP13    EQU base+$E0D   ;len=35
  162. OP14    EQU base+$100E  ;len=32
  163. OP15    EQU base+$D0F   ;len=3
  164. OP16    EQU base+$C10   ;len=21
  165. OP17    EQU base+$B11   ;len=39
  166. OP18    EQU base+$1312  ;len=34
  167. OP19    EQU base+$D13   ;len=3
  168. OP20    EQU base+$A14   ;len=23
  169. OP21    EQU base+$915   ;len=25
  170. OP22    EQU base+$D16   ;len=22
  171. OP23    EQU base+$1517  ;len=3
  172. OP24    EQU base+$818   ;len=5
  173. OP25    EQU base+$1619  ;len=41
  174. OP26    EQU base+$151A  ;len=7
  175. OP27    EQU base+$141B  ;len=3
  176. OP28    EQU base+$111C  ;len=38
  177. OP29    EQU base+$81D   ;len=41
  178. OP30    EQU base+$141E  ;len=38
  179. OP31    EQU base+$71F   ;len=3
  180. OP32    EQU base+$620   ;len=29
  181. OP33    EQU base+$1521  ;len=42
  182. OP34    EQU base+$722   ;len=3
  183. OP35    EQU base+$523   ;len=3
  184. OP36    EQU base+$424   ;len=32
  185. OP37    EQU base+$1225  ;len=20
  186. OP38    EQU base+$C26   ;len=17
  187. OP39    EQU base+$727   ;len=3
  188. OP40    EQU base+$528   ;len=49
  189. OP41    EQU base+$329   ;len=17
  190. OP42    EQU base+$72A   ;len=7
  191. OP43    EQU base+$172B  ;len=3
  192. OP44    EQU base+$D2C   ;len=47
  193. OP45    EQU base+$A2D   ;len=35
  194. OP46    EQU base+$172E  ;len=32
  195. OP47    EQU base+$102F  ;len=3
  196. OP48    EQU base+$E30   ;len=21
  197. OP49    EQU base+$F31   ;len=39
  198. OP50    EQU base+$1032  ;len=34
  199. OP51    EQU base+$933   ;len=3
  200. OP52    EQU base+$1334  ;len=37
  201. OP53    EQU base+$735   ;len=25
  202. OP54    EQU base+$936   ;len=22
  203. OP55    EQU base+$C37   ;len=3
  204. OP56    EQU base+$B38   ;len=4
  205. OP57    EQU base+$1239  ;len=41
  206. OP58    EQU base+$C3A   ;len=7
  207. OP59    EQU base+$33B   ;len=3
  208. OP60    EQU base+$B3C   ;len=53
  209. OP61    EQU base+$63D   ;len=41
  210. OP62    EQU base+$33E   ;len=38
  211. OP63    EQU base+$23F   ;len=3
  212. OP64    EQU base+$140   ;len=16
  213. OP65    EQU base+$C41   ;len=45
  214. OP66    EQU base+$1642  ;len=3
  215. OP67    EQU base+$1143  ;len=3
  216. OP68    EQU base+$1444  ;len=3
  217. OP69    EQU base+$1645  ;len=20
  218. OP70    EQU base+$1146  ;len=17
  219. OP71    EQU base+$1447  ;len=3
  220. OP72    EQU base+$E48   ;len=9
  221. OP73    EQU base+$849   ;len=17
  222. OP74    EQU base+$44A   ;len=8
  223. OP75    EQU base+$154B  ;len=3
  224. OP76    EQU base+$94C   ;len=17
  225. OP77    EQU base+$24D   ;len=35
  226. OP78    EQU base+$174E  ;len=32
  227. OP79    EQU base+$154F  ;len=3
  228. OP80    EQU base+$A50   ;len=24
  229. OP81    EQU base+$E51   ;len=39
  230. OP82    EQU base+$1552  ;len=37
  231. OP83    EQU base+$753   ;len=3
  232. OP84    EQU base+$1054  ;len=3
  233. OP85    EQU base+$455   ;len=25
  234. OP86    EQU base+$756   ;len=22
  235. OP87    EQU base+$1157  ;len=3
  236. OP88    EQU base+$1058  ;len=8
  237. OP89    EQU base+$1659  ;len=41
  238. OP90    EQU base+$135A  ;len=17
  239. OP91    EQU base+$115B  ;len=3
  240. OP92    EQU base+$F5C   ;len=3
  241. OP93    EQU base+$D5D   ;len=41
  242. OP94    EQU base+$115E  ;len=38
  243. OP95    EQU base+$F5F   ;len=3
  244. OP96    EQU base+$1060  ;len=15
  245. OP97    EQU base+$961   ;len=37
  246. OP98    EQU base+$1262  ;len=3
  247. OP99    EQU base+$F63   ;len=3
  248. OP100   EQU base+$864   ;len=14
  249. OP101   EQU base+$1265  ;len=15
  250. OP102   EQU base+$F66   ;len=17
  251. OP103   EQU base+$667   ;len=3
  252. OP104   EQU base+$A68   ;len=9
  253. OP105   EQU base+$569   ;len=24
  254. OP106   EQU base+$66A   ;len=8
  255. OP107   EQU base+$136B  ;len=3
  256. OP108   EQU base+$76C   ;len=42
  257. OP109   EQU base+$36D   ;len=30
  258. OP110   EQU base+$176E  ;len=32
  259. OP111   EQU base+$136F  ;len=3
  260. OP112   EQU base+$1070  ;len=24
  261. OP113   EQU base+$C71   ;len=34
  262. OP114   EQU base+$1372  ;len=29
  263. OP115   EQU base+$B73   ;len=3
  264. OP116   EQU base+$1274  ;len=19
  265. OP117   EQU base+$A75   ;len=20
  266. OP118   EQU base+$B76   ;len=22
  267. OP119   EQU base+$1577  ;len=3
  268. OP120   EQU base+$1478  ;len=8
  269. OP121   EQU base+$F79   ;len=36
  270. OP122   EQU base+$157A  ;len=17
  271. OP123   EQU base+$E7B   ;len=3
  272. OP124   EQU base+$87C   ;len=39
  273. OP125   EQU base+$67D   ;len=36
  274. OP126   EQU base+$E7E   ;len=38
  275. OP127   EQU base+$47F   ;len=3
  276. OP128   EQU base+$280   ;len=18
  277. OP129   EQU base+$581   ;len=35
  278. OP130   EQU base+$1682  ;len=3
  279. OP131   EQU base+$1483  ;len=3
  280. OP132   EQU base+$1184  ;len=15
  281. OP133   EQU base+$1685  ;len=13
  282. OP134   EQU base+$D86   ;len=18
  283. OP135   EQU base+$1487  ;len=3
  284. OP136   EQU base+$1288  ;len=5
  285. OP137   EQU base+$1089  ;len=18
  286. OP138   EQU base+$A8A   ;len=10
  287. OP139   EQU base+$158B  ;len=3
  288. OP140   EQU base+$B8C   ;len=30
  289. OP141   EQU base+$128D  ;len=28
  290. OP142   EQU base+$178E  ;len=33
  291. OP143   EQU base+$158F  ;len=3
  292. OP144   EQU base+$1390  ;len=20
  293. OP145   EQU base+$991   ;len=32
  294. OP146   EQU base+$1692  ;len=27
  295. OP147   EQU base+$1593  ;len=3
  296. OP148   EQU base+$1194  ;len=20
  297. OP149   EQU base+$C95   ;len=18
  298. OP150   EQU base+$1596  ;len=23
  299. OP151   EQU base+$A97   ;len=3
  300. OP152   EQU base+$D98   ;len=7
  301. OP153   EQU base+$799   ;len=34
  302. OP154   EQU base+$A9A   ;len=10
  303. OP155   EQU base+$109B  ;len=3
  304. OP156   EQU base+$49C   ;len=29
  305. OP157   EQU base+$F9D   ;len=34
  306. OP158   EQU base+$109E  ;len=38
  307. OP159   EQU base+$D9F   ;len=3
  308. OP160   EQU base+$3A0   ;len=14
  309. OP161   EQU base+$6A1   ;len=31
  310. OP162   EQU base+$DA2   ;len=17
  311. OP163   EQU base+$8A3   ;len=3
  312. OP164   EQU base+$13A4  ;len=17
  313. OP165   EQU base+$EA5   ;len=15
  314. OP166   EQU base+$AA6   ;len=20
  315. OP167   EQU base+$CA7   ;len=3
  316. OP168   EQU base+$11A8  ;len=7
  317. OP169   EQU base+$12A9  ;len=12
  318. OP170   EQU base+$CAA   ;len=10
  319. OP171   EQU base+$BAB   ;len=3
  320. OP172   EQU base+$5AC   ;len=32
  321. OP173   EQU base+$16AD  ;len=30
  322. OP174   EQU base+$15AE  ;len=35
  323. OP175   EQU base+$17AF  ;len=3
  324. OP176   EQU base+$11B0  ;len=20
  325. OP177   EQU base+$BB1   ;len=34
  326. OP178   EQU base+$17B2  ;len=31
  327. OP179   EQU base+$DB3   ;len=3
  328. OP180   EQU base+$EB4   ;len=22
  329. OP181   EQU base+$13B5  ;len=20
  330. OP182   EQU base+$12B6  ;len=25
  331. OP183   EQU base+$DB7   ;len=3
  332. OP184   EQU base+$CB8   ;len=8
  333. OP185   EQU base+$9B9   ;len=36
  334. OP186   EQU base+$DBA   ;len=12
  335. OP187   EQU base+$ABB   ;len=3
  336. OP188   EQU base+$7BC   ;len=38
  337. OP189   EQU base+$4BD   ;len=36
  338. OP190   EQU base+$ABE   ;len=41
  339. OP191   EQU base+$FBF   ;len=3
  340. OP192   EQU base+$CC0   ;len=15
  341. OP193   EQU base+$6C1   ;len=33
  342. OP194   EQU base+$FC2   ;len=3
  343. OP195   EQU base+$3C3   ;len=16
  344. OP196   EQU base+$11C4  ;len=18
  345. OP197   EQU base+$10C5  ;len=14
  346. OP198   EQU base+$FC6   ;len=16
  347. OP199   EQU base+$DC7   ;len=3
  348. OP200   EQU base+$14C8  ;len=5
  349. OP201   EQU base+$13C9  ;len=11
  350. OP202   EQU base+$ECA   ;len=5
  351. OP203   EQU base+$16CB  ;len=3
  352. OP204   EQU base+$DCC   ;len=33
  353. OP205   EQU base+$14CD  ;len=29
  354. OP206   EQU base+$16CE  ;len=31
  355. OP207   EQU base+$12CF  ;len=3
  356. OP208   EQU base+$ED0   ;len=20
  357. OP209   EQU base+$17D1  ;len=33
  358. OP210   EQU base+$15D2  ;len=31
  359. OP211   EQU base+$12D3  ;len=3
  360. OP212   EQU base+$13D4  ;len=3
  361. OP213   EQU base+$10D5  ;len=19
  362. OP214   EQU base+$12D6  ;len=21
  363. OP215   EQU base+$13D7  ;len=3
  364. OP216   EQU base+$11D8  ;len=18
  365. OP217   EQU base+$FD9   ;len=35
  366. OP218   EQU base+$13DA  ;len=11
  367. OP219   EQU base+$CDB   ;len=6
  368. OP220   EQU base+$BDC   ;len=3
  369. OP221   EQU base+$9DD   ;len=35
  370. OP222   EQU base+$8DE   ;len=37
  371. OP223   EQU base+$BDF   ;len=3
  372. OP224   EQU base+$5E0   ;len=15
  373. OP225   EQU base+$CE1   ;len=37
  374. OP226   EQU base+$BE2   ;len=3
  375. OP227   EQU base+$7E3   ;len=3
  376. OP228   EQU base+$EE4   ;len=18
  377. OP229   EQU base+$13E5  ;len=15
  378. OP230   EQU base+$BE6   ;len=16
  379. OP231   EQU base+$AE7   ;len=3
  380. OP232   EQU base+$10E8  ;len=5
  381. OP233   EQU base+$7E9   ;len=26
  382. OP234   EQU base+$14EA  ;len=6
  383. OP235   EQU base+$12EB  ;len=3
  384. OP236   EQU base+$AEC   ;len=33
  385. OP237   EQU base+$DED   ;len=30
  386. OP238   EQU base+$6EE   ;len=31
  387. OP239   EQU base+$16EF  ;len=3
  388. OP240   EQU base+$12F0  ;len=20
  389. OP241   EQU base+$5F1   ;len=34
  390. OP242   EQU base+$4F2   ;len=32
  391. OP243   EQU base+$17F3  ;len=3
  392. OP244   EQU base+$16F4  ;len=3
  393. OP245   EQU base+$10F5  ;len=20
  394. OP246   EQU base+$EF6   ;len=21
  395. OP247   EQU base+$17F7  ;len=3
  396. OP248   EQU base+$BF8   ;len=18
  397. OP249   EQU base+$3F9   ;len=36
  398. OP250   EQU base+$2FA   ;len=20
  399. OP251   EQU base+$17FB  ;len=3
  400. OP252   EQU base+$16FC  ;len=3
  401. OP253   EQU base+$1FD   ;len=36
  402. OP254   EQU base+$FE    ;len=37
  403. OP255   EQU base+$15FF  ;len=3
  404.  
  405.  
  406. ;A in A'
  407. ;N,C and Z of flags in F'
  408. ;B,D and I flags in (vXflag)
  409. ;V in (vVflag)
  410. ;X in IYL
  411. ;Y in IYH
  412. ;S (stack) in E', D' will always contain SPrealpage as a constant
  413. ;PC in DE
  414.  
  415. ;IX contains address of op_decode to do a fast jump to it (JP (IX) takes 8T)
  416.  
  417.         org PROGSTART
  418. begin
  419.         ld e,3+0x80 ;6912+keep
  420.         ;ld e,0+0x80 ;EGA+keep
  421.         OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
  422.         ;call setgfx
  423.  
  424.         ld e,0 ;color byte
  425.         OS_CLS
  426.  
  427.         OS_GETMAINPAGES
  428. ;dehl=pages in 0000,4000,8000,c000
  429.         ld a,e
  430.         ;ld (pgmain4000),a
  431.         ld a,h
  432.         ;ld (pgmain8000),a
  433.         ld a,l
  434.         ;ld (pgspr),a  
  435.  
  436.         ld a,(user_scr0_high) ;ok
  437.         SETPG4000
  438.  
  439.         ld hl,wasbasicrom
  440.         ld de,0xe000
  441.         ld bc,0x2000
  442.         ldir
  443.         ld hl,waskernalrom
  444.         ld de,0x6000
  445.         ld bc,0x2000
  446.         ldir
  447.         ld hl,wasloadfile
  448.         ld de,loadfile
  449.         ld bc,loadfile_sz
  450.         ldir
  451.  
  452.         ld hl,COMMANDLINE ;command line
  453.         call skipword
  454.         call skipspaces
  455.         ld a,(hl)
  456.         or a
  457.         jr z,noautoload
  458. ;command line = bk <file to load>"
  459.        ld (filenameaddr),hl
  460.        ;jr autoloadq
  461.        
  462. noautoload
  463. ;autoloadq
  464.         jp GO
  465. quit
  466.         im 1
  467.         ld hl,0
  468.         QUIT
  469.  
  470. wasloadfile
  471.         disp 0x5b00
  472. loadfile
  473.         im 1
  474.         push af
  475.         push bc
  476.         push de
  477.         push hl
  478.         push ix
  479.         push iy
  480.         exx
  481.         ex af,af' ;'
  482.         push af
  483.         push bc
  484.         push de
  485.         push hl
  486. filenameaddr=$+1
  487.         ld de,0
  488.        
  489.       ;ld hl,(0x7ffe)
  490.       ;push hl
  491. ;de=filename
  492.         OS_OPENHANDLE
  493.         push bc
  494.         ld de,loadfileaddr;0x7ffe
  495.         ld hl,2;0x2002
  496.         OS_READHANDLE
  497.         pop bc
  498. loadfileaddr=$+1
  499.         ld de,0
  500.        ld hl,0x2000
  501.        or a
  502.        sbc hl,de
  503.         ld a,d
  504.         and 0x1f
  505.         or 0x80
  506.         ld d,a
  507.         ;ld hl,0x2000
  508.         push bc
  509.         OS_READHANDLE
  510.         pop bc
  511.         ld de,0x0200 ;next 8K
  512.         ld hl,0x1e00
  513.         push bc
  514.         OS_READHANDLE
  515.         pop bc
  516.         OS_CLOSEHANDLE
  517.       ;pop hl
  518.       ;ld (0x7ffe),hl
  519.         pop hl
  520.         pop de
  521.         pop bc
  522.         pop af
  523.         ex af,af' ;'
  524.         exx
  525.         pop iy
  526.         pop ix
  527.         pop hl
  528.         pop de
  529.         pop bc
  530.         pop af
  531.         im 2
  532.         ret
  533.         ent
  534. loadfile_sz=$-wasloadfile
  535.  
  536. skipword
  537. ;hl=string
  538. ;out: hl=terminator/space addr
  539. getword0
  540.         ld a,(hl)
  541.         or a
  542.         ret z
  543.         cp ' '
  544.         ret z
  545.         inc hl
  546.         jr getword0
  547.  
  548. skipspaces
  549. ;hl=string
  550. ;out: hl=after last space
  551.         ld a,(hl)
  552.         cp ' '
  553.         ret nz
  554.         inc hl
  555.         jr skipspaces
  556.  
  557. wasbasicrom
  558.         incbin "vic20.rom"
  559.  
  560.         org 0x8000 ;will be 8k RAM
  561. waskernalrom
  562.         incbin "vic20a.rom"
  563.         org 0xa000
  564.         incbin "vic20f.rom"
  565.  
  566. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  567.         ORG base-$0200
  568. GO
  569.         DI              ;as we're messing with IX/IY disable interrupts!
  570.  
  571.                         ;6502 gets contents of
  572.                         ;?FFFC and ?FFFD
  573.                         ;and jumps to their contents
  574.         LD SP,base-$20  ;for some reason TIMEX machines have silly values for SP!
  575.         LD A,IM2page
  576.         LD I,A
  577.         IM 2            ;we want to trap interrupts so we can simulate 6502 IRQ
  578.  
  579.         LD A,$05
  580.         LD BC,$1FFD
  581.         NOP             ;these bytes can be changed to OUT (C),A
  582.         NOP
  583.  
  584. superinit:
  585.         LD BC,$FFFD     ;now port $FFFD
  586.         LD A,$07
  587.         OUT (C),A       ;select mixer control (R7)
  588.         LD A,B          ;A=255 = all silent
  589.         LD B,$BF        ;port BFFD now
  590.         OUT (C),A       ;select tone only on channels A,B and C
  591.  
  592. reset:
  593.         LD HL,(FFrealpage*256)+$FC
  594.                         ;HL points to RESET vector on virtual machine
  595.         LD E,(HL)
  596.         INC HL
  597.         LD D,(HL)       ;DE now contains correct PC value
  598.         EXX
  599.         LD DE,$0000
  600.         PUSH DE         ;used to set AF' later
  601.         LD D,SPrealpage
  602.         DEC E           ;change E from 0 to FF, so SP starts at 01FF
  603.         EXX
  604.         LD HL,vXflag
  605.         LD (HL),$34     ;on reset 6502 sets bit 5 (undef), 4 (brk), 2 (irq)
  606.                         ;and resets bit 3 (dec). The rest are undefined
  607.         DEC HL
  608.         LD (HL),$00
  609.         LD HL,VIC900F
  610.         INC (HL)        ;force a change in background colour - forces graphics to redraw screen
  611.                
  612.         LD IY,$0000     ;X/Y to 0
  613.         LD HL,trapback2here
  614.         POP AF          ;set A and flags to 0
  615.        
  616.         PUSH HL         ;preload stack with right address
  617.         DEC DE          ;dec PC by 1 to compensate for CLD increasing it
  618.         EI              ;safe to enable interrupts now
  619.         LD IX,rVIC900F  ;need to reset display after sorting out BCD mode
  620.         JP cld          ;make sure ADC/SBC are correct
  621.                         ;it will JP (IX) into rVIC900F which will sort the screen out
  622.                         ;and will reset IX to op_decode
  623.  
  624. vVflag:
  625.         DB $00
  626. vXflag:
  627.         DB $00
  628.  
  629. vtemp:
  630.         DW $00
  631.  
  632.  
  633. m1wrap:
  634. ;INC E has caused PC to wrap to next page
  635. ;therefore we have to re-translate DE
  636.  
  637.         INC D           ;next page
  638.         LD L,D
  639.         LD H,M1page
  640.         LD H,(HL)       ;translated address in HL once LD L,E done
  641.                         ;but that's done outside m1wrap routine
  642.         RET
  643.  
  644.  
  645. ;increments PC by one
  646. ;used after most instructions
  647.         macro incPC
  648.         INC DE
  649.         JP (IX)
  650.         endm
  651.  
  652.         macro nextbyte
  653.         INC DE
  654.         LD L,D
  655.         LD H,M1page
  656.         LD H,(HL)
  657.         LD L,E
  658.         endm
  659.  
  660. ;start with AF flags paged in
  661. ;end with them paged out
  662.         macro opPHP
  663.         LD HL,(vVflag)
  664.         JR NZ,$+4
  665.         SET 1,H
  666.         JR NC,$+4
  667.         SET 0,H
  668.         JP P,$+5
  669.         SET 7,H
  670.         EX AF,AF' ;'
  671.         LD A,H
  672.         OR L
  673.         endm
  674. ;L contains I,D,5 and B flags to be added
  675. ;notice that A is NOT PUSHED onto the stack!
  676. ;EX AF,AF' must also be done outside macro
  677. ;this MUST be done outside the macro
  678. ;(this is because BRK and IRQ have different requirements for B flag)
  679.  
  680. ;pushes value in A on 6502 stack
  681. ;best to do this with AF paged out to preserve 6502/Z80 flags
  682.         macro do_pushA
  683.         EXX
  684.         LD (DE),A
  685.         DEC E
  686.         EXX
  687.         endm
  688.  
  689.  
  690.  
  691. ; "illegal" opcodes come here
  692.  
  693. illegal3:
  694.         INC DE          ;skip 3 bytes
  695. illegal2:
  696.         INC DE          ;skip 2 bytes
  697. illegal:
  698.         EX AF,AF' ;'
  699.         LD A,$02
  700.         OUT ($FE),A     ;make border red for now
  701.         EX AF,AF' ;'
  702.         incPC           ;skip just one byte
  703.  
  704.  
  705. nmi_handler:
  706.         LD HL,(M1page*256)+$26  ;LD H,$M1page instead of JR $-4
  707.                                 ;$26 is opcode for LD H,nn
  708.         LD (op_decode+1),HL     ;reset 2 bytes to what they normally are
  709.  
  710.          call loadfile ;FIXME!
  711.  
  712. ;PC (DE) is already correct at this point - so stack it
  713.  
  714.         EX AF,AF' ;'
  715.         LD A,D
  716.         do_pushA
  717.         LD A,E
  718.         do_pushA
  719.         LD HL,(FFrealpage*256)+$FA      ;pre-validated page 255 value used
  720.                         ;to get true NMI address
  721.         LD E,(HL)
  722.         INC L           ;safe to do as we know HL has to be FFFA - therfore validated page still valid
  723.                         ;also L will never overflow so quicker to do INC L than INC HL
  724.         LD D,(HL)       ;DE (PC) now contains  vector
  725.  
  726.         EX AF,AF' ;'
  727.         opPHP           ;prepare flags in A to be stacked
  728. ;correct flags are in A
  729.         AND $EF         ;force B bit clear (like IRQ)
  730.         do_pushA        ;stack flags
  731.  
  732.         LD HL,vXflag
  733.         LD A,(HL)
  734.         AND $E3         ;clear bits 4,3 and 2
  735.         OR $14          ;have to set bit 2 (I) 
  736.         LD (HL),A
  737.         EX AF,AF' ;'
  738.         JP (IX)         ;no incPC as DE (PC) is already correct
  739.  
  740. signalNMI:
  741. ;currently an IRQ could override an NMI which is wrong!
  742.  
  743.         LD HL,$18+(irqND*256)
  744.                                 ;force interrupt to be serviced once
  745.                                 ;current 6502 instruction has finished
  746.         LD (op_decode+1),HL     ;overwrite with JR irqN instruction
  747.         RET                     ;eventually code will get to nmi_handler
  748.  
  749.  
  750. ;this is the main opcode decoding routine
  751. ;every 6502 instruction starts at op_decode.
  752.  
  753. irqN:   JP nmi_handler
  754. irqM:   JP irq_handler
  755.  
  756. op_decode:
  757.         LD L,D
  758.         LD H,M1page     ;interrupts will overwrite this byte pair with a JR to irqM or irqN instruction
  759.                         ;Remember - trapped I/O will alter IX, interrupts alter code.
  760.                         ;(otherwise you can lose I/O or IRQ depending on order they happen)
  761.                         ;This instruction is changed rather than first instruction as
  762.                         ;2 bytes have to be changed and Z80 IRQ could occur in between the 2
  763.                         ;instructions causing the Z80 to interpret the LD H,M1page as something
  764.                         ;completely different
  765.  
  766. ;remember DE contains the 6502 program counter
  767. ;we're now "translating" a 6502 page to a ZX Spectrum page
  768. ;ie: address $1000 (page $10) on the VIC translates into address $9000 (page $90) on the Spectrum
  769. ;see the M1 page table near the end of the code
  770.  
  771.         LD H,(HL)
  772.         LD L,E          ;HL now contains translated address
  773.  
  774. ;now HL contains a translated address we need to get the opcode at that address
  775.  
  776.         LD L,(HL)
  777.  
  778. ;and work out address of routine to call
  779.  
  780.         LD H,Oppage
  781.         LD H,(HL)
  782.  
  783. ;each 6502 routine starts at an address where it's lsb = opcode value
  784. ;ie: RTS = opcode $60, so you'll find the RTS routine begins at $xx60
  785.  
  786.         JP (HL)         ;47T just to decode the opcode!
  787.                         ;you can see the virtual 6502 is going to be a lot slower than the real thing!
  788.                         ;adding INC DE and JP (IX) brings it up to 61T
  789.                         ;therefore the shortest 6502 instruction (NOP) takes 61T to run
  790.                         ;which gives 0.057 MIPS on a real Spectrum!
  791.                         ;the real 6502 @1 MHz could do 0.5 MIPS - we are therefore nearly 9 times slower
  792.                         ;in reality it is more like x15 times slower
  793.  
  794.  
  795. irqND   EQU 256-(op_decode+3-irqN)      ;calculate JR displacements for self modifying-code
  796. irqMD   EQU 256-(op_decode+3-irqM)
  797.  
  798. trapback2here:
  799. ;TRAPS will come back here
  800. ;traps are currently not used in this VIC 20 implmentation of 6502 core
  801.  
  802.         LD A,$04
  803.         OUT ($FE),A
  804.         DI
  805.         HALT
  806.  
  807. ;use this macro for BRAnch instructions (they don't have the INC DE bit)
  808.         macro nextbyteB
  809.         LD L,D
  810.         LD H,M1page
  811.         LD H,(HL)
  812.         LD L,E
  813.         endm
  814.  
  815. ;use this macro when HL still contains validated address of DE
  816. ;#define nextbyte2              INC E
  817. ;#defcont               \       CALL Z,m1wrap
  818. ;#defcont               \       LD L,E
  819.  
  820.         macro nextbyte2
  821.         INC DE
  822.         LD L,D
  823.         LD H,M1page
  824.         LD H,(HL)
  825.         LD L,E
  826.         endm
  827.  
  828. ;L(msb) and C(lsb) must be correct before using macro
  829.         macro readtrap
  830.         LD H,MRpage
  831.         LD H,(HL)
  832.         DEC H
  833.         CALL Z,RAMread_trap
  834.         LD L,C
  835.         endm
  836.  
  837. ;L(msb) and C(lsb) must be correct before using macro
  838.         macro writetrap
  839.         LD H,MWpage
  840.         LD H,(HL)
  841.         DEC H
  842.         CALL Z,RAMwrite_trap
  843.         LD L,C
  844.         endm
  845.  
  846. ;zero page
  847. ;a1=?PC
  848. ;d=?a1  (where a1 msb=00)
  849.         macro getZP_read
  850.         nextbyte
  851.         LD L,(HL)
  852.         LD H,ZPrealpage
  853.         endm
  854.  
  855. ;zero page,X
  856. ;a1=?PC
  857. ;d=?(a1+X)      (where a1 msb=00)
  858.         macro getZPX_read
  859.         nextbyte
  860.         DB $FD
  861.         LD A,L
  862.         ADD A,(HL)
  863.         LD L,A
  864.         LD H,ZPrealpage
  865.         endm
  866.  
  867. ;zero page,Y
  868. ;a1=?PC
  869. ;d=?(a1+Y)      (where a1 msb=00)
  870.         macro getZPY_read
  871.         nextbyte
  872.         DB $FD
  873.         LD A,H
  874.         ADD A,(HL)
  875.         LD L,A
  876.         LD H,ZPrealpage
  877.         endm
  878.  
  879. ;(indirect zero page)
  880. ;a1=?PC
  881. ;a2=?a1+256*?(a1+1)
  882. ;d=?a2
  883.         macro get_ZP_read
  884.         nextbyte
  885.         LD L,(HL)
  886.         LD H,ZPrealpage
  887.         LD C,(HL)
  888.         INC HL
  889.         LD L,(HL)
  890. ;new address in HL (well it would be if LD H,(HL) was done instead along with LD L,C being added)
  891. ;but we need to validate this new address and that only needs msb
  892.         readtrap
  893.         endm
  894.  
  895. ;absolute_read
  896. ;a1=?PC+256*?(PC+1)
  897. ;d=?a1
  898.         macro getabsolute_read
  899.         nextbyte
  900.         LD C,(HL)
  901.         nextbyte2
  902.         LD L,(HL)
  903.         readtrap
  904.         endm
  905.  
  906. ;absolute_RWM
  907. ;a1=?PC+256*?(PC+1)
  908. ;d=?a1
  909.         macro getabsolute_RWM
  910.         nextbyte
  911.         LD C,(HL)
  912.         nextbyte2
  913.         LD B,(HL)
  914.         PUSH BC
  915.         LD L,B
  916.         writetrap               //this sets IX
  917.         POP BC
  918.         LD L,B
  919.         readtrap
  920.         endm
  921.  
  922. ;absolute_read,X
  923. ;a1=?PC+256*?(PC+1)
  924. ;a2=a1+X
  925. ;d=?a2
  926.         macro getabsoluteX_read
  927.         nextbyte
  928.         LD A,(HL)
  929.         DB $FD
  930.         ADD A,L
  931.         LD C,A
  932. ;correct lo-byte stored in C for use later
  933.         nextbyte2
  934. ;BC would contains new absolute_read address, but we haven't set B yet - it's at (HL)
  935. ;now add X to it
  936. ;C,A and CFlag not affected by nextbyte(2)
  937.         LD A,$00
  938.         ADC A,(HL)
  939. ;would've been ADC A,B - but quicker to use ADC A,(HL) and ditch earlier LD B,(HL)
  940. ;need to add carry in case C+X overflowed from earlier
  941. ;thus the value in A is the correct hi-byte.
  942.         LD L,A
  943. ;however the validation routine requires hi-byte in L
  944.         readtrap
  945.         endm
  946.  
  947. ;absolute_read,Y
  948. ;a1=?PC+256*?(PC+1)
  949. ;a2=a1+Y
  950. ;d=?a2
  951.         macro getabsoluteY_read
  952.         nextbyte
  953.         LD A,(HL)
  954.         DB $FD
  955.         ADD A,H
  956.         LD C,A
  957. ;correct lo-byte stored in C for use later
  958.         nextbyte2
  959.         LD A,$00
  960.         ADC A,(HL)
  961.         LD L,A
  962.         readtrap
  963.         endm
  964.  
  965. ;(indirect,X)
  966. ;a=(?PC)+X where msb=00
  967. ;a2=?a+256*?(a+1)
  968. ;d=?a2
  969.         macro indirectX_read
  970.         nextbyte
  971.         DB $FD
  972.         LD A,L
  973.         ADD A,(HL)
  974.         LD L,A
  975.         LD H,ZPrealpage
  976. ;validated address in HL. We've used ADD A,L because address at this point is always page 0
  977.         LD C,(HL)
  978.         INC HL
  979. ;address is always validated because page 1 always follows page 0, and HL is 0-$FF
  980.         LD L,(HL)
  981. ;validate new address (a2)
  982.         readtrap
  983.         endm
  984.  
  985. ;(indirect),Y
  986. ;a=?PC
  987. ;a2=?a+256*?(a+1)
  988. ;a3=a2+Y
  989. ;d=?a3
  990.         macro indirectY_read
  991.         nextbyte
  992.         LD L,(HL)
  993. ;we know H=0 at this point (zero page), so validate it using ZPrealpage constant
  994.         LD H,ZPrealpage
  995.         LD A,(HL)
  996.         INC HL
  997. ;even if HL goes from FF to 00 (ie: into Page 1), the validated page 1 address is always +1 of validated page 0 address
  998. ;BC would contain new pointer - just got to add Y to it. B is still at (HL) and C is in A
  999.         DB $FD
  1000.         ADD A,H
  1001.         LD C,A
  1002. ;store lo-byte of result in C for later
  1003.         LD A,$00
  1004.         ADC A,(HL)
  1005. ;would've been ADC A,B - but quicker to use ADC A,(HL) and ditch earlier LD B,(HL)
  1006. ;need to add carry in case C+Y overflowed earlier
  1007. ;this is hi-byte of result, but validation routine requires
  1008. ;hi-byte in L so instead of saving in H we save in L
  1009.         LD L,A
  1010.         readtrap
  1011.         endm
  1012.  
  1013. ;*** WRITE to memory versions***
  1014.  
  1015. ;zero page
  1016. ;a1=?PC
  1017. ;d=?a1  (where a1 msb=00)
  1018.         macro getZP_write
  1019.         nextbyte
  1020.         LD L,(HL)
  1021.         LD H,ZPrealpage
  1022.         endm
  1023.  
  1024. ;zero page,X
  1025. ;a1=?PC
  1026. ;d=?(a1+X)      (where a1 msb=00)
  1027.         macro getZPX_write
  1028.         nextbyte
  1029.         DB $FD
  1030.         LD A,L
  1031.         ADD A,(HL)
  1032.         LD L,A
  1033.         LD H,ZPrealpage
  1034.         endm
  1035.  
  1036. ;zero page,Y
  1037. ;a1=?PC
  1038. ;d=?(a1+Y)      (where a1 msb=00)
  1039.         macro getZPY_write
  1040.         nextbyte
  1041.         DB $FD
  1042.         LD A,H
  1043.         ADD A,(HL)
  1044.         LD L,A
  1045.         LD H,ZPrealpage
  1046.         endm
  1047.  
  1048. ;(indirect zero page)
  1049. ;a1=?PC
  1050. ;a2=?a1+256*?(a1+1)
  1051. ;d=?a2
  1052.         macro get_ZP_write
  1053.         nextbyte
  1054.         LD L,(HL)
  1055.         LD H,ZPrealpage
  1056.         LD C,(HL)
  1057.         INC HL
  1058.         LD L,(HL)
  1059. ;new address in HL (well it would be if LD H,(HL) was done instead along with LD L,C being added)
  1060. ;but we need to validate this new address and that only needs msb
  1061.         writetrap
  1062.         endm
  1063.  
  1064. ;absolute
  1065. ;a1=?PC+256*?(a1+1)
  1066. ;d=?a1
  1067.         macro getabsolute_write
  1068.         nextbyte
  1069.         LD C,(HL)
  1070.         nextbyte2
  1071.         LD L,(HL)
  1072.         writetrap
  1073.         endm
  1074.  
  1075. ;absolute,X
  1076. ;a1=?PC+256*?(a1+1)
  1077. ;a2=a1+X
  1078. ;d=?a2
  1079.         macro getabsoluteX_write
  1080.         nextbyte
  1081.         LD A,(HL)
  1082.         DB $FD
  1083.         ADD A,L
  1084.         LD C,A
  1085. ;correct lo-byte stored in C for use later
  1086.         nextbyte2
  1087. ;BC would contains new absolute_read address, but we haven't set B yet - it's at (HL)
  1088. ;now add X to it
  1089. ;C,A and CFlag not affected by nextbyte(2)
  1090.         LD A,$00
  1091.         ADC A,(HL)
  1092. ;would've been ADC A,B - but quicker to use ADC A,(HL) and ditch earlier LD B,(HL)
  1093. ;need to add carry in case C+X overflowed from earlier
  1094. ;thus the value in A is the correct hi-byte.
  1095.         LD L,A
  1096. ;however the validation routine requires hi-byte in L
  1097.         writetrap
  1098.         endm
  1099.  
  1100. ;absolute,Y
  1101. ;a1=?PC+256*?(a1+1)
  1102. ;a2=a1+Y
  1103. ;d=?a2
  1104.         macro getabsoluteY_write
  1105.         nextbyte
  1106.         LD A,(HL)
  1107.         DB $FD
  1108.         ADD A,H
  1109.         LD C,A
  1110. ;correct lo-byte stored in C for use later
  1111.         nextbyte2
  1112.         LD A,$00
  1113.         ADC A,(HL)
  1114.         LD L,A
  1115.         writetrap
  1116.         endm
  1117.  
  1118. ;(indirect,X)
  1119. ;a=(?PC)+X where msb=00
  1120. ;a2=?a+256*?(a+1)
  1121. ;d=?a2
  1122.         macro indirectX_write
  1123.         nextbyte
  1124.         DB $FD
  1125.         LD A,L
  1126.         ADD A,(HL)
  1127.         LD L,A
  1128.         LD H,ZPrealpage
  1129. ;validated address in HL. We've used ADD A,L because address at this point is always page 0
  1130.         LD C,(HL)
  1131.         INC HL
  1132. ;address is always validated because page 1 always follows page 0, and HL is 0-$FF
  1133.         LD L,(HL)
  1134. ;validate new address (d2)
  1135.         writetrap
  1136.         endm
  1137.  
  1138. ;(indirect),Y
  1139. ;a=?PC
  1140. ;a2=?a+256*?(a+1)
  1141. ;a3=a2+Y
  1142. ;d=?a3
  1143.         macro indirectY_write
  1144.         nextbyte
  1145.         LD L,(HL)
  1146. ;we know H=0 at this point (zero page), so validate it using ZPrealpage constant
  1147.         LD H,ZPrealpage
  1148.         LD A,(HL)
  1149.         INC HL
  1150. ;even if HL goes from FF to 00 (ie: into Page 1), the validated page 1 address is always +1 of validated page 0 address
  1151. ;BC would contain new pointer - just got to add Y to it. B is still at (HL) and C is in A
  1152.         DB $FD
  1153.         ADD A,H
  1154.         LD C,A
  1155. ;store lo-byte of result in C for later
  1156.         LD A,$00
  1157.         ADC A,(HL)
  1158. ;need to add carry in case C+Y overflowed earlier
  1159. ;this is hi-byte of result, but validation routine requires
  1160. ;hi-byte in L so instead of saving in H we save in L
  1161.         LD L,A
  1162.         writetrap
  1163.         endm
  1164.  
  1165.  
  1166.  
  1167. ;the sequence INC A / DEC A gets the Z80 to set the S (6502 N flag)
  1168. ;and Z flags correctly - without touching the C flag (which OR A would do)
  1169.  
  1170. ;LDA - load accumulator
  1171. ;set Z and N only
  1172.         macro opLDA
  1173.         LD A,(HL)
  1174.         INC A
  1175.         DEC A
  1176.         endm
  1177.  
  1178. ;LDX - load X reg
  1179. ;set Z and N only
  1180.         macro opLDX
  1181.         LD B,(HL)
  1182.         INC B
  1183.         DEC B
  1184.         DB $FD
  1185.         LD L,B
  1186.         endm
  1187.  
  1188. ;LDY - load Y reg
  1189. ;set Z and N only
  1190.         macro opLDY
  1191.         LD B,(HL)
  1192.         INC B
  1193.         DEC B
  1194.         DB $FD
  1195.         LD H,B
  1196.         endm
  1197.  
  1198. ;DEC - decrease by one
  1199. ;set Z and N only
  1200.         macro opDEC
  1201.         DEC (HL)
  1202.         endm
  1203. ;flags set correctly by DEC instruction in this case
  1204.  
  1205.  
  1206. ;INC - increase by one
  1207. ;set Z and N only
  1208.         macro opINC
  1209.         INC (HL)
  1210.         endm
  1211. ;flags set correctly by INC instruction in this case
  1212.  
  1213.  
  1214. ;CPY - compare with Y
  1215. ;set Z,N and C only
  1216.         macro opCPY
  1217.         LD B,A
  1218.         DB $FD
  1219.         LD A,H
  1220.         CP (HL)
  1221.         CCF
  1222. ;flags set correctly by CP instruction in this case, except Carry flag
  1223. ;which for some reason is the opposite on 6502 compared to Z80
  1224.         LD A,B
  1225.         endm
  1226.  
  1227.  
  1228. ;CPX - compare with X
  1229. ;set Z,N and C only
  1230.         macro opCPX
  1231.         LD B,A
  1232.         DB $FD
  1233.         LD A,L
  1234.         CP (HL)
  1235.         CCF
  1236. ;flags set correctly by CP instruction in this case, except Carry flag
  1237. ;which for some reason is the opposite on 6502 compared to Z80
  1238.         LD A,B
  1239.         endm
  1240.  
  1241.  
  1242. ;CMP - compare with A
  1243. ;set Z,N and C only
  1244.         macro opCMP
  1245.         CP (HL)
  1246.         CCF
  1247.         endm
  1248. ;flags set correctly by CP instruction in this case, except Carry flag
  1249. ;which for some reason is the opposite on 6502 compared to Z80
  1250.  
  1251. ;STA - store A in memory
  1252. ;no flags affected
  1253.         macro opSTA
  1254.         LD (HL),A
  1255.         endm
  1256.  
  1257. ;STX - store X in memory
  1258. ;no flags affected
  1259.         macro opSTX
  1260.         DB $FD
  1261.         LD B,L
  1262.         LD (HL),B
  1263.         endm
  1264.  
  1265. ;STY - store Y in memory
  1266. ;no flags affected
  1267.         macro opSTY
  1268.         DB $FD
  1269.         LD B,H
  1270.         LD (HL),B
  1271.         endm
  1272.  
  1273. ;STZ - clear memory
  1274. ;no flags affected
  1275.         macro opSTZ
  1276.         LD (HL),$00
  1277.         endm
  1278.  
  1279. ;AND - bitwise AND against A
  1280. ;set Z and N only
  1281. ;Z80 clears C so have to be careful!
  1282.         macro opAND
  1283.         JR NC,$+7
  1284.         AND (HL)
  1285.         SCF
  1286. ;put carry back to how it was
  1287.         incPC
  1288.         AND (HL)
  1289. ;carry was already clear so doesn't matter about Z80 clearing it
  1290. ;JP to here
  1291.         endm
  1292.  
  1293. ;ORA - bitwise OR against A
  1294. ;set Z and N only
  1295. ;Z80 clears C so have to be careful!
  1296.         macro opORA
  1297.         JR NC,$+7
  1298.         OR (HL)
  1299.         SCF
  1300. ;put carry back to how it was
  1301.         incPC
  1302.         OR (HL)
  1303. ;carry was already clear so doesn't matter about Z80 clearing it
  1304. ;JP to here
  1305.         endm
  1306.  
  1307. ;EOR - bitwise EOR against A
  1308. ;set Z and N only
  1309. ;Z80 clears C so have to be careful!
  1310.         macro opEOR
  1311.         JR NC,$+7
  1312.         XOR (HL)
  1313.         SCF
  1314. ;put carry back to how it was
  1315.         incPC
  1316.         XOR (HL)
  1317. ;carry was already clear so doesn't matter about Z80 clearing it
  1318. ;JP to here
  1319.         endm
  1320.  
  1321. ;ADC - add with carry to A
  1322. ;sets C,Z,V and N flags
  1323.         macro opADC
  1324.         JP sharedadc2
  1325.         endm
  1326.  
  1327.  
  1328. ;TRB - test and reset bits
  1329. ;sets Z flag only
  1330.         macro opTRB
  1331.         PUSH AF
  1332.         CPL
  1333.         AND (HL)
  1334.         LD (HL),A
  1335.         JR NZ,$+$06
  1336. ;result was 0, so we need to set Z flag (and Z flag only!)
  1337.         POP HL
  1338. ;flags in L
  1339.         SET 6,L
  1340. ;set Z flag (bit 6 on Z80)
  1341.         PUSH HL
  1342. ;back here from earlier JR
  1343.         POP AF
  1344.         endm
  1345.  
  1346. ;TSB - test and set bits
  1347. ;sets Z flag only
  1348.         macro opTSB
  1349.         PUSH AF
  1350.         OR (HL)
  1351.         LD (HL),A
  1352.         JR NZ,$+$06
  1353. ;result was 0, so we need to set Z flag (and Z flag only!)
  1354.         POP HL
  1355. ;flags in L
  1356.         SET 6,L
  1357. ;set Z flag (bit 6 on Z80)
  1358.         PUSH HL
  1359. ;back here from earlier JR
  1360.         POP AF
  1361.         endm
  1362.  
  1363. ;ASL - arithmetic shift left
  1364. ;sets C,Z and N flags
  1365.         macro opASL
  1366.         SLA (HL)
  1367.         endm
  1368.  
  1369. ;LSR - logical shift right
  1370. ;sets C,Z and N flags
  1371.         macro opLSR
  1372.         SRL (HL)
  1373.         endm
  1374.  
  1375. ;ROL - rotate left one bit
  1376. ;sets C,Z and N flags
  1377.         macro opROL
  1378.         RL (HL)
  1379.         endm
  1380.  
  1381. ;ROR - rotate right one bit
  1382. ;sets C,Z and N flags
  1383.         macro opROR
  1384.         RR (HL)
  1385.         endm
  1386.  
  1387. ;SBC - subtract with carry from accumulator
  1388. ;sets C,Z,V and N flags
  1389.         macro opSBC
  1390.         JP sharedsbc2
  1391.         endm
  1392.  
  1393. ;BIT - test bits against accumulator (AND without storing result)
  1394. ;sets Z,V and N flags
  1395. ;except BIT #imm which only sets Z (CMOS)
  1396.         macro opBIT
  1397.         LD B,A
  1398.         LD C,(HL)
  1399.         INC C
  1400.         DEC C
  1401.         PUSH AF
  1402.         LD A,C
  1403.         AND $40
  1404.         LD (vVflag),A
  1405.         LD A,B
  1406.         AND C
  1407.         JR NZ,$+6
  1408.         POP HL
  1409.         SET 6,L
  1410.         PUSH HL
  1411.         POP AF
  1412.         endm
  1413.  
  1414.  
  1415. WriteScreen:
  1416.         LD IX,op_decode
  1417. RAMtrap EQU $+1
  1418.         LD HL,RAMtrap   ;this value gets overwritten as required
  1419. WriteDirect:
  1420.         EX AF,AF' ;'    ;save 6502 AF
  1421.         LD C,(HL)       ;get contents of that byte - to be used later
  1422.         LD A,H
  1423.         PUSH DE         ;preserve DE (PC)
  1424.                         ;on VIC it's 23 lines of 22 chars!
  1425.         SUB ScreenPage  ;make address become an offset of 0000-01FF
  1426.         LD H,A          ;HL contains offset
  1427. WriteScreenSize:
  1428. ;the following parameters can be adjusted by POKEing the VIC
  1429.         LD DE,$FFEA     ;-22 chars per row!
  1430.         LD B,$17        ;23 rows
  1431.                         ;if B=0 here then trouble arises...
  1432. write0:
  1433.         ADD HL,DE
  1434.         JR NC,write1
  1435.         DJNZ write0
  1436.  
  1437.         JP display7bytes8       ;outside range of ZX screen so abort
  1438.                                 ;or some clever person set col size to 0!
  1439.                                 ;have to jump to this addr and not "write3"
  1440.                                 ;as we don't know if we're in 8 or 16 row mode
  1441. write1:
  1442. ;at this point B sort of contains number of rows
  1443. ;and the remainder in HL (should be <255 so use just L) is number of columns
  1444.  
  1445.         LD A,$17
  1446.         SUB B           ;row count in A
  1447.  
  1448.         SBC HL,DE       ;correct for taking off 1 too many rows
  1449.                         ;CF cleared by SUB B above
  1450.  
  1451.         ADD A,A         ;double up so if A was 3, it's now 6
  1452.         LD E,A
  1453.         LD D,rowtable/256       ;rowtable msb - DE points to correct entry in table
  1454.         EX DE,HL        ;now HL points there
  1455.         LD (RAMtrap),HL ;store for later
  1456.         LD A,(HL)
  1457.         INC L
  1458.         LD D,(HL)
  1459.         ADD A,E         ;add in column from HL (now DE)
  1460.         LD E,A          ;DE now contains correct addr on screen
  1461.  
  1462.  
  1463. writescreen3:
  1464.         LD L,C          ;C contains (HL) from earlier
  1465.         LD H,$00        ;copy into HL
  1466.  
  1467. writescreen4:
  1468.         ADD HL,HL       ;contains NOP for 8 high characters
  1469.                         ;or ADD HL,HL for 16 high characters
  1470.         ADD HL,HL       ;multiply by 2
  1471.         ADD HL,HL       ;multiply by 4
  1472.         ADD HL,HL       ;multiply by 8
  1473. WriteScreenCharset:
  1474.         LD BC,chargen
  1475.         ADD HL,BC       ;reference into character map
  1476. write2:
  1477.         LD A,(HL)
  1478.         LD (DE),A
  1479.         INC D
  1480.         INC L           ;safe to use INC L rather than INC HL as charmap always on 1024 byte boundary
  1481.         LD A,(HL)
  1482.         LD (DE),A
  1483.         INC D
  1484.         INC L
  1485.         LD A,(HL)
  1486.         LD (DE),A
  1487.         INC D
  1488.         INC L
  1489.         LD A,(HL)
  1490.         LD (DE),A
  1491.         INC D
  1492.         INC L
  1493.         LD A,(HL)
  1494.         LD (DE),A
  1495.         INC D
  1496.         INC L
  1497.         LD A,(HL)
  1498.         LD (DE),A
  1499.         INC D
  1500.         INC L
  1501.         LD A,(HL)
  1502.         LD (DE),A
  1503.         INC D
  1504.         INC L
  1505.         LD A,(HL)
  1506.         LD (DE),A       ;don't need last 2 INC D/L - no point!
  1507.  
  1508. write3:
  1509. write3a:
  1510. ;the following 7 (8!!!) bytes change depending on 8 or 16 row display mode
  1511.         LD A,E
  1512.         AND $1F         ;keep column
  1513.         LD B,A          ;in B for safe keeping
  1514.         LD DE,(RAMtrap)
  1515.  
  1516.         INC E
  1517.         INC E           ;INC DE twice to get to next row (2nd half of 16-bytes)
  1518.         LD A,(DE)
  1519.         LD C,A
  1520.         INC E
  1521.         LD A,(DE)
  1522.         LD D,A
  1523.         LD A,B          ;column
  1524.         ADD A,C         ;add to DE
  1525.         LD E,A          ;new row addr in DE
  1526.                         ;HL continues where we left off
  1527. write16:
  1528.         LD A,(HL)
  1529.         LD (DE),A
  1530.         INC D
  1531.         INC L           ;safe to use INC L rather than INC HL as charmap always on 1024 byte boundary
  1532.         LD A,(HL)
  1533.         LD (DE),A
  1534.         INC D
  1535.         INC L
  1536.         LD A,(HL)
  1537.         LD (DE),A
  1538.         INC D
  1539.         INC L
  1540.         LD A,(HL)
  1541.         LD (DE),A
  1542.         INC D
  1543.         INC L
  1544.         LD A,(HL)
  1545.         LD (DE),A
  1546.         INC D
  1547.         INC L
  1548.         LD A,(HL)
  1549.         LD (DE),A
  1550.         INC D
  1551.         INC L
  1552.         LD A,(HL)
  1553.         LD (DE),A
  1554.         INC D
  1555.         INC L
  1556.         LD A,(HL)
  1557.         LD (DE),A       ;don't need last 2 INC D/L - no point!
  1558.        
  1559. display7bytes8:
  1560.         POP DE          ;restore PC
  1561.         EX AF,AF' ;'    ;back to using real AF
  1562.         JP (IX)
  1563.  
  1564. display7bytes16:
  1565.         LD A,E
  1566.         AND $1F         ;keep column
  1567.         LD B,A          ;in B for safe keeping
  1568.         LD DE,(RAMtrap) ;yes I know that makes 8 bytes!!
  1569.  
  1570.         EX AF,AF' ;'    ;back to using real AF
  1571.         JP (IX)
  1572.  
  1573. attr2:
  1574.         EX AF,AF' ;'    ;preserve 6502 AF
  1575.         LD IX,op_decode
  1576.         PUSH DE         ;preserve DE
  1577.         LD HL,(RAMtrap) ;get back what we wrote to earlier
  1578.  
  1579. ;ATTR3-$0B IS HERE
  1580. attr30B:
  1581.         PUSH HL         ;preserve it for later
  1582.         LD A,H
  1583.         AND $01         ;this clears CF flag
  1584.         LD H,A          ;HL now contains 0-1FF = offset from top left
  1585.         LD DE,(WriteScreenSize+1)       ;width in DE
  1586.         LD B,$17        ;max 24 rows - value changed as necessary
  1587. attr3:
  1588.         ADD HL,DE
  1589.         JR NC,attr4
  1590.         DJNZ attr3
  1591.         POP HL          ;drop HL off stack
  1592.         JR attrEnd      ;outside screen area so abort!
  1593. attr4:
  1594.         SBC HL,DE       ;compensate for going too far
  1595. attr4a:
  1596.         LD A,$17        ;this value is changed as necessary
  1597.         SUB B           ;row counter in A
  1598.                         ;remainder (column) in L
  1599. attr316:
  1600.         NOP             ;this is NOP for 8-row high chars or
  1601.                         ;ADD A,A for 16-row high chars!
  1602.  
  1603.         LD C,L          ;copy col to C for later
  1604.         ADD A,A         ;safe to double up in 8 bits
  1605.                         ;as row should be <32
  1606.         ADD A,A         ;x4
  1607.         ADD A,A         ;x8
  1608.         LD L,A
  1609.         LD H,$16        ;now go to 16 bit addition
  1610.                         ;set H to $0B, so when x8 it goes to $58
  1611.                         ;set H to $16, so when x4 it goes to $58
  1612.                         ;which is $5800 for attribute area
  1613.         ADD HL,HL       ;x16
  1614.         ADD HL,HL       ;x32 - 32 bytes per row
  1615.         LD A,L
  1616.         ADD A,C         ;include columns
  1617.         LD L,A
  1618.  
  1619.         POP DE          ;get earlier RAMtrap addr back as DE
  1620.         LD A,(DE)
  1621.         AND $07         ;keep only colour nybble - ignore multicolour
  1622.         LD B,A          ;INK into B
  1623.  
  1624.         LD A,(VIC900F)  ;get background colour
  1625.                         ;are we inversed?
  1626.  
  1627. attr4b: ;patch jr nc/c
  1628.         JR NC,attr5     ;C is always RESET by AND entry above
  1629.  
  1630. attr6:
  1631. ;no inverse
  1632.         AND $F0         ;by keeping only bits 7-4
  1633.         OR B            ;merge in INK
  1634.         JP attr7
  1635.  
  1636. attr5:
  1637. ;inverse
  1638.         AND $F0
  1639.         OR B
  1640.         RRCA
  1641.         RRCA
  1642.         RRCA
  1643.         RRCA            ;swap INK and PAPER nybbles
  1644.  
  1645. attr7:
  1646. ;A now contains 0-255 value which we reference into table to convert into Spectrum ATTR value
  1647.  
  1648.         LD E,A
  1649.         LD D,attrs/256
  1650.         LD A,(DE)       ;convert VIC value (bbbb0fff) into ZX ATTR value
  1651.         LD (HL),A       ;update Spectrum screen
  1652.  
  1653. attrEnd:
  1654.         POP DE          ;restore DE
  1655.        
  1656.         EX AF,AF' ;'    ;restore 6502 AF
  1657.         JP (IX)
  1658.  
  1659.  
  1660.         ORG base-$20
  1661. RELOCATE_KERNAL:
  1662.         LD HL,$8000
  1663.         LD DE,$6000
  1664.         LD BC,$2000
  1665.         LDIR
  1666.         JP base-$0200
  1667.  
  1668.         ORG base-$08
  1669. ANTIPRG:
  1670.         LD HL,$FF72
  1671.         LD ($7FFE),HL
  1672.         JP (IX)
  1673.  
  1674. ;start of routines
  1675.  
  1676.         ORG base
  1677.  
  1678. brk:
  1679.         INC DE          ;skip past BRK instruction
  1680.         INC DE          ;remember BRK increases PC by 1 to skip following byte
  1681.                         ;before stacking PC - unlike JSR
  1682.         EX AF,AF'
  1683.         LD A,D
  1684.         do_pushA
  1685.         LD A,E
  1686.         do_pushA
  1687.         LD HL,FFrealpage*256+$FE        ;validate it!
  1688.         LD E,(HL)
  1689.         INC L           ;safe to do as we know HL has to be FFFE - therfore validated page still valid
  1690.                         ;also L will never overflow so quicker to do INC L than INC HL
  1691.         LD D,(HL)       ;DE (PC) now contains  vector
  1692.  
  1693.         EX AF,AF'
  1694.         opPHP           ;prepare flags in A
  1695.         OR $10          ;force B flag to be set (only IRQ pushes this bit as 0)
  1696.  
  1697. ;correct flags are in A
  1698.         do_pushA
  1699.  
  1700.         LD HL,vXflag
  1701.         LD A,(HL)
  1702.         AND $E3         ;clear bits 4,3 and 2
  1703.         OR $14          ;have to set bits 4 (B) and 2 (I)      
  1704.         LD (HL),A
  1705.         EX AF,AF'
  1706.         JP (IX)         ;no incPC as DE (PC) is already correct
  1707.  
  1708.         ORG OP1
  1709. ora_zpx:
  1710.         EX AF,AF'
  1711.         indirectX_read
  1712.         EX AF,AF'
  1713.         opORA
  1714.         incPC
  1715.  
  1716.         ORG OP2
  1717.         JP illegal2
  1718.  
  1719.         ORG OP3
  1720.         JP illegal
  1721.  
  1722.         ORG OP4
  1723. tsbzp:
  1724.         getZP_read
  1725.         opTSB
  1726.         incPC
  1727.  
  1728.         ORG OP5
  1729. orazp:
  1730.         getZP_read
  1731.         opORA
  1732.         incPC
  1733.  
  1734.         ORG OP6
  1735. aslzp:
  1736.         getZP_read
  1737.         opASL
  1738.         incPC
  1739.  
  1740.         ORG OP7
  1741.         JP illegal
  1742.  
  1743.         ORG OP8
  1744. php:
  1745. ;start with flags in...
  1746.         opPHP
  1747. ;flags now out
  1748.         OR $10          ;force B flag to be set (only IRQ pushes this bit as 0)
  1749.         do_pushA
  1750.         EX AF,AF'
  1751.         incPC
  1752.  
  1753.         ORG OP9
  1754. ora_imm:
  1755.         nextbyte
  1756.         opORA
  1757.         incPC
  1758.  
  1759.         ORG OP10
  1760. ;ASL - arithmetic shift left
  1761. ;sets C,Z and N flags
  1762. asla:   SLA A
  1763.         incPC
  1764.  
  1765.         ORG OP11
  1766.         JP illegal
  1767.  
  1768.         ORG OP12
  1769. tsbA:
  1770.         EX AF,AF'
  1771.         getabsolute_read
  1772.         EX AF,AF'
  1773.         opTSB
  1774.         incPC
  1775.  
  1776.         ORG OP13
  1777. oraA:
  1778.         EX AF,AF'
  1779.         getabsolute_read
  1780.         EX AF,AF'
  1781.         opORA
  1782.         incPC
  1783.  
  1784.         ORG OP14
  1785. aslA:
  1786.         EX AF,AF'
  1787.         getabsolute_read
  1788.         EX AF,AF'
  1789.         opASL
  1790.         incPC
  1791.  
  1792.         ORG OP15
  1793.         JP illegal
  1794.  
  1795.         ORG OP16
  1796. bpl:
  1797.         INC DE
  1798.         JP M,bpl2
  1799.         EX AF,AF'
  1800.         nextbyteB
  1801.         LD L,(HL)
  1802.         LD A,L
  1803.         RLCA
  1804.         SBC A,A
  1805.         LD H,A
  1806.         ADD HL,DE       ;add displacement to PC (DE)
  1807.         EX DE,HL
  1808.         EX AF,AF'
  1809. bpl2:
  1810.         incPC
  1811.  
  1812.         ORG OP17
  1813. ora_zp_y:
  1814.         EX AF,AF'
  1815.         indirectY_read
  1816.         EX AF,AF'
  1817.         opORA
  1818.         incPC
  1819.  
  1820.         ORG OP18
  1821. ora_zp:
  1822.         get_ZP_read
  1823.         opORA
  1824.         incPC
  1825.  
  1826.         ORG OP19
  1827.         JP illegal
  1828.  
  1829.         ORG OP20
  1830. trbzp:
  1831.         getZP_read
  1832.         opTRB
  1833.         incPC
  1834.  
  1835.         ORG OP21
  1836. orazpx:
  1837.         EX AF,AF'
  1838.         getZPX_read
  1839.         EX AF,AF'
  1840.         opORA
  1841.         incPC
  1842.  
  1843.         ORG OP22
  1844. aslzpx:
  1845.         EX AF,AF'
  1846.         getZPX_read
  1847.         EX AF,AF'
  1848.         opASL
  1849.         incPC
  1850.  
  1851.         ORG OP23
  1852.         JP illegal
  1853.  
  1854.         ORG OP24
  1855. clc:
  1856.         SCF
  1857.         CCF             ;no clear carry flag on Z80, so have to set then compliment it!
  1858.         incPC
  1859.  
  1860.         ORG OP25
  1861. oraay:
  1862.         EX AF,AF'
  1863.         getabsoluteY_read
  1864.         EX AF,AF'
  1865.         opORA
  1866.         incPC
  1867.  
  1868.         ORG OP26
  1869. ;INC - increase by one
  1870. ;set Z and N only
  1871. inca:   INC A
  1872. ;flags set correctly by INC instruction in this case
  1873.         incPC
  1874.  
  1875.         ORG OP27
  1876.         JP illegal
  1877.  
  1878.         ORG OP28
  1879. trbA:
  1880.         EX AF,AF'
  1881.         getabsolute_read
  1882.         EX AF,AF'
  1883.         opTRB
  1884.         incPC
  1885.  
  1886.         ORG OP29
  1887. oraax:
  1888.         EX AF,AF'
  1889.         getabsoluteX_read
  1890.         EX AF,AF'
  1891.         opORA
  1892.         incPC
  1893.  
  1894.         ORG OP30
  1895. aslax:
  1896.         EX AF,AF'
  1897.         getabsoluteX_read
  1898.         EX AF,AF'
  1899.         opASL
  1900.         incPC
  1901.  
  1902.         ORG OP31
  1903.         JP illegal
  1904.  
  1905.         ORG OP32
  1906. jsrA:
  1907.         EX AF,AF'
  1908.         nextbyte
  1909.         LD C,(HL)
  1910.         nextbyte2
  1911.         LD A,D
  1912.         do_pushA        ;we're pushing PC+2 here rather than PC+3 (ie: byte after JSR b1b2)
  1913.         LD A,E          ;as RTS does +1 to POP'd result
  1914.         do_pushA
  1915.         LD E,C
  1916.         LD D,(HL)       ;quicker to do this than LD B,(HL) , LD D,B
  1917.         EX AF,AF'
  1918.         JP (IX)         ;go straight to decode routine
  1919.  
  1920.         ORG OP33
  1921. and_zpx:
  1922.         EX AF,AF'
  1923.         indirectX_read
  1924.         EX AF,AF'
  1925.         opAND
  1926.         incPC
  1927.  
  1928.         ORG OP34
  1929.         JP illegal2
  1930.  
  1931.         ORG OP35
  1932.         JP illegal
  1933.  
  1934.         ORG OP36
  1935. bitzp:
  1936.         getZP_read
  1937.         opBIT
  1938.         incPC
  1939.  
  1940.         ORG OP37
  1941. andzp:
  1942.         getZP_read
  1943.         opAND
  1944.         incPC
  1945.  
  1946.         ORG OP38
  1947. rolzp:
  1948.         getZP_read
  1949.         opROL
  1950.         incPC
  1951.  
  1952.         ORG OP39
  1953.         JP illegal
  1954.  
  1955.         ORG OP40
  1956. plp:
  1957.         LD B,A          ;keep A
  1958.         EXX
  1959.         INC E           ;SP is 0100-01FF only
  1960.         LD A,(DE)
  1961.         EXX
  1962. plp2:
  1963.         LD C,A          ;take copy of flags!
  1964.         AND $40
  1965.         LD L,A
  1966.  
  1967.         LD A,C
  1968.         AND $3C
  1969.         OR $20
  1970.         LD H,A
  1971.         LD (vVflag),HL  ;53T
  1972.  
  1973.         LD A,C          ;restore flags
  1974.         AND $83         ;keep N+C+Z flags (6502)
  1975.         ADD A,$3E       ;move Z flag from bit 1 to bit 6 if it was set
  1976.         LD C,A          ;new flags in L
  1977.         PUSH BC         ;(B has real 6502 Acc from earlier)
  1978.         LD A,(adcdaa2)
  1979.         XOR H
  1980.         AND $08         ;=0 at this point means we don't need to change BCD mode
  1981.         JR NZ,plp32
  1982.  
  1983.         POP AF          ;reset C,Z,N flags
  1984.         incPC
  1985. plp32:
  1986.         BIT 3,H
  1987.         JR NZ,plp42
  1988.         POP AF
  1989.         JP cld2
  1990. plp42:
  1991.         POP AF          ;reset C,Z,N flags
  1992.         JP sed2         ;jump into SED routine
  1993.  
  1994.         ORG OP41
  1995. and_imm:
  1996.         nextbyte
  1997.         opAND
  1998.         incPC
  1999.  
  2000.         ORG OP42
  2001. ;ROL - rotate left one bit
  2002. ;sets C,Z and N flags
  2003. rola:   ADC A,A         ;can't use RLA (4T) as it doesn't set Z and N flags
  2004.                         ;ADC A,A does same as "RL A" (except H and V flags), but is 4T quicker
  2005.         incPC
  2006.  
  2007.         ORG OP43
  2008.         JP illegal
  2009.  
  2010.         ORG OP44
  2011. bitA:
  2012.         EX AF,AF'
  2013.         getabsolute_read
  2014.         EX AF,AF'
  2015.         opBIT
  2016.         incPC
  2017.  
  2018.         ORG OP45
  2019. andA:
  2020.         EX AF,AF'
  2021.         getabsolute_read
  2022.         EX AF,AF'
  2023.         opAND
  2024.         incPC
  2025.  
  2026.         ORG OP46
  2027. rolA:
  2028.         EX AF,AF'
  2029.         getabsolute_read
  2030.         EX AF,AF'
  2031.         opROL
  2032.         incPC
  2033.  
  2034.         ORG OP47
  2035.         JP illegal
  2036.  
  2037.  
  2038.         ORG OP48
  2039. bmi:
  2040.         INC DE
  2041.         JP P,bmi2
  2042.         EX AF,AF'
  2043.         nextbyteB
  2044.         LD L,(HL)
  2045.         LD A,L
  2046.         RLCA
  2047.         SBC A,A
  2048.         LD H,A
  2049.         ADD HL,DE       ;add displacement to PC (DE)
  2050.         EX DE,HL
  2051.         EX AF,AF'
  2052. bmi2:
  2053.         incPC
  2054.  
  2055.         ORG OP49
  2056. and_zp_y:
  2057.         EX AF,AF'
  2058.         indirectY_read
  2059.         EX AF,AF'
  2060.         opAND
  2061.         incPC
  2062.  
  2063.         ORG OP50
  2064. and_zp:
  2065.         get_ZP_read
  2066.         opAND
  2067.         incPC
  2068.  
  2069.         ORG OP51
  2070.         JP illegal
  2071.  
  2072.         ORG OP52
  2073. bitzpx:
  2074.         EX AF,AF'
  2075.         getZPX_read
  2076.         EX AF,AF'
  2077.         opBIT
  2078.         incPC
  2079.  
  2080.         ORG OP53
  2081. andzpx:
  2082.         EX AF,AF'
  2083.         getZPX_read
  2084.         EX AF,AF'
  2085.         opAND
  2086.         incPC
  2087.  
  2088.         ORG OP54
  2089. rolzpx:
  2090.         EX AF,AF'
  2091.         getZPX_read
  2092.         EX AF,AF'
  2093.         opROL
  2094.         incPC
  2095.  
  2096.         ORG OP55
  2097.         JP illegal
  2098.  
  2099.         ORG OP56
  2100. sec:
  2101.         SCF
  2102.         incPC
  2103.  
  2104.         ORG OP57
  2105. anday:
  2106.         EX AF,AF'
  2107.         getabsoluteY_read
  2108.         EX AF,AF'
  2109.         opAND
  2110.         incPC
  2111.  
  2112.         ORG OP58
  2113. ;DEC - decrease by one
  2114. ;set Z and N only
  2115. deca:   DEC A
  2116. ;flags set correctly by DEC instruction in this case
  2117.         incPC
  2118.  
  2119.         ORG OP59
  2120.         JP illegal
  2121.  
  2122.         ORG OP60
  2123. bitax:
  2124.         EX AF,AF'
  2125.         getabsoluteX_read
  2126.         EX AF,AF'
  2127.         opBIT
  2128.         incPC
  2129.  
  2130.         ORG OP61
  2131. andax:
  2132.         EX AF,AF'
  2133.         getabsoluteX_read
  2134.         EX AF,AF'
  2135.         opAND
  2136.         incPC
  2137.  
  2138.         ORG OP62
  2139. rolax:
  2140.         EX AF,AF'
  2141.         getabsoluteX_read
  2142.         EX AF,AF'
  2143.         opROL
  2144.         incPC
  2145.  
  2146.         ORG OP63
  2147.         JP illegal
  2148.  
  2149.         ORG OP64
  2150. rti:
  2151. ;pops address and status register
  2152. ;doesn't +1 to PC!
  2153. ;now doesn't destroy H'L'
  2154.         LD B,A          ;keep 6502 Acc for PLP2
  2155.         EXX
  2156.         INC E
  2157.         LD A,(DE)       ;status byte off stack first
  2158.         INC E
  2159.         PUSH DE
  2160.         INC E           ;another 2 bytes off stack
  2161.         EXX
  2162.         POP HL
  2163.         LD E,(HL)       ;lo byte next
  2164.         INC L
  2165.         LD D,(HL)       ;hi byte last
  2166.         DEC DE          ;adjust PC so the incPC at end of PLP
  2167.                         ;doesn't affect us
  2168.         JP plp2         ;carry on inside PLP (we've still got wrong AF)
  2169.  
  2170.  
  2171.         ORG OP65
  2172. eor_zpx:
  2173.         EX AF,AF'
  2174.         indirectX_read
  2175.         EX AF,AF'
  2176.         opEOR
  2177.         incPC
  2178.  
  2179.         ORG OP66
  2180.         JP illegal2
  2181.  
  2182.         ORG OP67
  2183.         JP illegal
  2184.  
  2185.         ORG OP68
  2186.         JP illegal2
  2187.  
  2188.         ORG OP69
  2189. eorzp:
  2190.         getZP_read
  2191.         opEOR
  2192.         incPC
  2193.  
  2194.         ORG OP70
  2195. lsrzp:
  2196.         getZP_read
  2197.         opLSR
  2198.         incPC
  2199.        
  2200.         ORG OP71
  2201.         JP illegal
  2202.  
  2203.         ORG OP72
  2204. ;PHA - push A
  2205. ;no flags affected
  2206. pha:
  2207.         EXX
  2208.         LD (DE),A
  2209.         EX AF,AF'
  2210.         DEC E
  2211.         EX AF,AF'
  2212.         EXX
  2213.         incPC
  2214.  
  2215.         ORG OP73
  2216. eor_imm:
  2217.         nextbyte
  2218.         opEOR
  2219.         incPC
  2220.  
  2221.         ORG OP74
  2222. ;LSR - logical shift right
  2223. ;sets C,Z and N flags
  2224. lsra:   SRL A
  2225.         incPC
  2226.  
  2227.         ORG OP75
  2228.         JP illegal
  2229.  
  2230.         ORG OP76
  2231. jmpA:
  2232.         nextbyte
  2233.         LD C,(HL)
  2234.         nextbyte2
  2235.         LD D,(HL)
  2236.         LD E,C
  2237.         JP (IX)
  2238.  
  2239.         ORG OP77
  2240. eorA:
  2241.         EX AF,AF'
  2242.         getabsolute_read
  2243.         EX AF,AF'
  2244.         opEOR
  2245.         incPC
  2246.        
  2247.         ORG OP78
  2248. lsrA:
  2249.         EX AF,AF'
  2250.         getabsolute_read
  2251.         EX AF,AF'
  2252.         opLSR
  2253.         incPC
  2254.  
  2255.         ORG OP79
  2256.         JP illegal
  2257.  
  2258.         ORG OP80
  2259. bvc:
  2260.         EX AF,AF'
  2261.         INC DE
  2262.         LD A,(vVflag)
  2263.         AND A           ;is it zero?
  2264.         JR NZ,bvc2
  2265.         nextbyteB
  2266.         LD L,(HL)
  2267.         LD A,L
  2268.         RLCA
  2269.         SBC A,A
  2270.         LD H,A
  2271.         ADD HL,DE       ;add displacement to PC (DE)
  2272.         EX DE,HL
  2273. bvc2:
  2274.         EX AF,AF'
  2275.         incPC
  2276.  
  2277.         ORG OP81
  2278. eor_zp_y:
  2279.         EX AF,AF'
  2280.         indirectY_read
  2281.         EX AF,AF'
  2282.         opEOR
  2283.         incPC
  2284.  
  2285.         ORG OP82
  2286. eor_zp:
  2287.         get_ZP_read
  2288.         opEOR
  2289.         incPC
  2290.  
  2291.         ORG OP83
  2292.         JP illegal
  2293.  
  2294.         ORG OP84
  2295.         JP illegal2
  2296.  
  2297.         ORG OP85
  2298. eorzpx:
  2299.         EX AF,AF'
  2300.         getZPX_read
  2301.         EX AF,AF'
  2302.         opEOR
  2303.         incPC
  2304.  
  2305.         ORG OP86
  2306. lsrzpx:
  2307.         EX AF,AF'
  2308.         getZPX_read
  2309.         EX AF,AF'
  2310.         opLSR
  2311.         incPC
  2312.  
  2313.         ORG OP87
  2314.         JP illegal
  2315.  
  2316.         ORG OP88
  2317. cli:
  2318.         LD HL,vXflag
  2319.         RES 2,(HL)      ;reset I bit
  2320.         incPC
  2321.  
  2322.         ORG OP89
  2323. eoray:
  2324.         EX AF,AF'
  2325.         getabsoluteY_read
  2326.         EX AF,AF'
  2327.         opEOR
  2328.         incPC
  2329.  
  2330.         ORG OP90
  2331. ;PHY - push Y
  2332. ;no flags affected
  2333. phy:
  2334.         EXX
  2335.         EX AF,AF'
  2336.  
  2337.         DB $FD
  2338.         LD A,H
  2339.  
  2340.         LD (DE),A
  2341.         DEC E
  2342.         EX AF,AF'
  2343.         EXX
  2344.         incPC
  2345.  
  2346.         ORG OP91
  2347.         JP illegal
  2348.  
  2349.         ORG OP92
  2350.         JP illegal3
  2351.  
  2352.         ORG OP93
  2353. eorax:
  2354.         EX AF,AF'
  2355.         getabsoluteX_read
  2356.         EX AF,AF'
  2357.         opEOR
  2358.         incPC
  2359.  
  2360.         ORG OP94
  2361. lsrax:
  2362.         EX AF,AF'
  2363.         getabsoluteX_read
  2364.         EX AF,AF'
  2365.         opLSR
  2366.         incPC
  2367.  
  2368.         ORG OP95
  2369.         JP illegal
  2370.  
  2371.         ORG OP96
  2372. rts:
  2373. ;pops address and adds 1!
  2374.         EX AF,AF'
  2375.         EXX
  2376.         INC E
  2377.         LD A,(DE)       ;lo-byte off stack first
  2378.         EXX
  2379.         LD E,A          ;set lo-byte of PC
  2380.         EXX
  2381.         INC E
  2382.         LD A,(DE)       ;hi-byte off stack
  2383.         EXX
  2384.         LD D,A          ;DE now contains value off stack
  2385.         EX AF,AF'
  2386.         incPC           ;incPC does the +1 to PC for us
  2387.  
  2388.         ORG OP97
  2389. adc_zpx:
  2390.         EX AF,AF'
  2391.         indirectX_read
  2392.         EX AF,AF'
  2393.         opADC
  2394.         incPC
  2395.  
  2396.         ORG OP98
  2397.         JP illegal2
  2398.  
  2399.         ORG OP99
  2400.         JP illegal
  2401.  
  2402.         ORG OP100
  2403. stzzp:
  2404.         getZP_write
  2405.         opSTZ
  2406.         incPC
  2407.  
  2408.         ORG OP101
  2409. adczp:
  2410.         getZP_read
  2411.         opADC
  2412.         incPC
  2413.  
  2414.         ORG OP102
  2415. rorzp:
  2416.         getZP_read
  2417.         opROR
  2418.         incPC
  2419.  
  2420.         ORG OP103
  2421.         JP illegal
  2422.  
  2423.         ORG OP104
  2424. ;PLA - pull A
  2425. ;sets Z and N flags
  2426. pla:
  2427.         EXX
  2428.         INC E           ;this will upset flags - but we're going to change them anyway!
  2429.         LD A,(DE)
  2430.         INC A
  2431.         DEC A
  2432.         EXX
  2433.         incPC
  2434.  
  2435.         ORG OP105
  2436. adc_imm:
  2437.         nextbyte
  2438.  
  2439. ;every other ADC instruction has to JP to here
  2440. ;but ADC #imm carries straight on into code
  2441.  
  2442. sharedadc2:
  2443. ;all ADC opcodes come here - it's quicker to waste 10T
  2444. ;on a JP instruction then to test D flag and JP according to it
  2445.  
  2446.         ADC A,(HL)
  2447. ;the following byte is modified by SED and CLD instructions
  2448. ;to either NOP (CLD) or DAA (SED)
  2449.  
  2450. adcdaa2:
  2451.         DAA
  2452.  
  2453. ;C,Z and N are correct
  2454. ;but V needs to be stored elsewhere
  2455.  
  2456.         LD HL,vVflag
  2457.         JP PO,$+8
  2458. ;jump if overflow unset
  2459. ;A=$40 if V set, A=0 if V reset
  2460.         LD (HL),$40
  2461.         incPC
  2462. ;no overflow comes here
  2463.         LD (HL),$00
  2464.         incPC
  2465.  
  2466.         ORG OP106
  2467. ;ROR - rotate right one bit
  2468. ;sets C,Z and N flags
  2469. rora:   RR A            ;can't use RRA (4T) as it doesn't set Z and N flags
  2470.         incPC
  2471.  
  2472.         ORG OP107
  2473.         JP illegal
  2474.  
  2475.         ORG OP108
  2476. jmp_a:
  2477.         EX AF,AF'
  2478.         nextbyte
  2479.         LD C,(HL)
  2480.         nextbyte2
  2481.         LD D,(HL)
  2482.         LD E,C          ;address following JMP into DE
  2483.         LD L,D          ;pre-load L for readtrap (C already OK)
  2484.         readtrap
  2485.         LD B,(HL)
  2486.         INC DE
  2487.         LD C,E
  2488.         LD L,D          ;pre-load L and C for readtrap
  2489.         readtrap
  2490.         LD D,(HL)
  2491.         LD E,B          ;get (DE) into PC
  2492.         EX AF,AF'
  2493.         JP (IX)
  2494.  
  2495.         ORG OP109
  2496. adcA:
  2497.         EX AF,AF'
  2498.         getabsolute_read
  2499.         EX AF,AF'
  2500.         opADC
  2501.         incPC
  2502.  
  2503.         ORG OP110
  2504. rorA:
  2505.         EX AF,AF'
  2506.         getabsolute_read
  2507.         EX AF,AF'
  2508.         opROR
  2509.         incPC
  2510.  
  2511.         ORG OP111
  2512.         JP illegal
  2513.  
  2514.         ORG OP112
  2515. bvs:
  2516.         EX AF,AF'
  2517.         INC DE
  2518.         LD A,(vVflag)
  2519.         AND A           ;is it zero?
  2520.         JR Z,bvs2
  2521.         nextbyteB
  2522.         LD L,(HL)
  2523.         LD A,L
  2524.         RLCA
  2525.         SBC A,A
  2526.         LD H,A
  2527.         ADD HL,DE       ;add displacement to PC (DE)
  2528.         EX DE,HL
  2529. bvs2:
  2530.         EX AF,AF'
  2531.         incPC
  2532.  
  2533.         ORG OP113
  2534. adc_zp_y:
  2535.         EX AF,AF'
  2536.         indirectY_read
  2537.         EX AF,AF'
  2538.         opADC
  2539.         incPC
  2540.  
  2541.         ORG OP114
  2542. adc_zp:
  2543.         get_ZP_read
  2544.         opADC
  2545.         incPC
  2546.  
  2547.         ORG OP115
  2548.         JP illegal
  2549.  
  2550.         ORG OP116
  2551. stzzpx:
  2552.         EX AF,AF'
  2553.         getZPX_write
  2554.         EX AF,AF'
  2555.         opSTZ
  2556.         incPC
  2557.        
  2558.         ORG OP117
  2559. adczpx:
  2560.         EX AF,AF'
  2561.         getZPX_read
  2562.         EX AF,AF'
  2563.         opADC
  2564.         incPC
  2565.  
  2566.         ORG OP118
  2567. rorzpx:
  2568.         EX AF,AF'
  2569.         getZPX_read
  2570.         EX AF,AF'
  2571.         opROR
  2572.         incPC
  2573.  
  2574.         ORG OP119
  2575.         JP illegal
  2576.  
  2577.         ORG OP120
  2578. sei:
  2579.         LD HL,vXflag
  2580.         SET 2,(HL)      ;set I bit
  2581.         incPC
  2582.  
  2583.         ORG OP121
  2584. adcay:
  2585.         EX AF,AF'
  2586.         getabsoluteY_read
  2587.         EX AF,AF'
  2588.         opADC
  2589.         incPC
  2590.  
  2591.         ORG OP122
  2592. ;PLY - pull Y
  2593. ;sets Z and N flags
  2594. ply:
  2595.         EXX
  2596.         EX AF,AF'
  2597.         INC E
  2598.         LD A,(DE)
  2599.         EXX
  2600.         LD B,A
  2601.         EX AF,AF'
  2602.         INC B
  2603.         DEC B
  2604.         DB $FD
  2605.         LD H,B
  2606.         incPC
  2607.  
  2608.         ORG OP123
  2609.         JP illegal
  2610.  
  2611.         ORG OP124
  2612. jmp_ax:
  2613. ;this is a one off instruction, but it's similar to absoluteX_read...
  2614.         EX AF,AF'
  2615.         nextbyte
  2616.         LD C,(HL)
  2617.         nextbyte2
  2618.         LD B,(HL)
  2619.         DB $FD
  2620.         LD A,L
  2621.         LD L,A
  2622.         LD H,$00
  2623.         ADD HL,BC       ;now got address + X in HL
  2624.         EX DE,HL        ;set DE to this address
  2625.         nextbyteB       ;don't increase DE as it's already correct!
  2626.         LD C,(HL)
  2627.         nextbyte2
  2628.         LD D,(HL)
  2629.         LD E,C          ;DE now contains new addr for PC
  2630.         EX AF,AF'
  2631.         JP (IX)
  2632.  
  2633.         ORG OP125
  2634. adcax:
  2635.         EX AF,AF'
  2636.         getabsoluteX_read
  2637.         EX AF,AF'
  2638.         opADC
  2639.         incPC
  2640.  
  2641.         ORG OP126
  2642. rorax:
  2643.         EX AF,AF'
  2644.         getabsoluteX_read
  2645.         EX AF,AF'
  2646.         opROR
  2647.         incPC
  2648.  
  2649.         ORG OP127
  2650.         JP illegal
  2651.  
  2652.         ORG OP128
  2653. bra:    EX AF,AF'
  2654.         nextbyte
  2655.         LD L,(HL)       ;displacement
  2656.         LD A,L          ;copy into A
  2657.         RLCA            ;bit 7 into C flag
  2658.         SBC A,A         ;if C=0 then A=0, C=1 then A=FF
  2659.         LD H,A          ;which is correct value for H in HL
  2660.         ADD HL,DE       ;add displacement to PC (DE)
  2661.         EX DE,HL
  2662.         EX AF,AF'
  2663.         incPC
  2664.  
  2665.         ORG OP129
  2666. sta_zpx:
  2667.         EX AF,AF'
  2668.         indirectX_write
  2669.         EX AF,AF'
  2670.         opSTA
  2671.         incPC
  2672.  
  2673.         ORG OP130
  2674.         JP illegal2
  2675.  
  2676.         ORG OP131
  2677.         JP illegal
  2678.  
  2679.         ORG OP132
  2680. styzp:
  2681.         getZP_write
  2682.         opSTY
  2683.         incPC
  2684.  
  2685.         ORG OP133
  2686. stazp:
  2687.         getZP_write
  2688.         opSTA
  2689.         incPC
  2690.  
  2691.         ORG OP134
  2692. stxzp:
  2693.         getZP_write
  2694.         opSTX
  2695.         incPC
  2696.  
  2697.         ORG OP135
  2698.         JP illegal
  2699.  
  2700.         ORG OP136
  2701. dey:    DB $FD
  2702.         DEC H
  2703. ;flags set correctly by DEC instruction in this case
  2704.         incPC
  2705.  
  2706.         ORG OP137
  2707. bit_imm:
  2708.         PUSH AF         ;get flags and 6502 A
  2709.         nextbyte
  2710. ;BIT #imm does not set V and N flags, so we can't use opBIT
  2711.         AND (HL)        ;do the BIT test against the immediate value
  2712.         JR NZ,$+6       ;if A<>0 then skip setting real Z flag
  2713.         POP BC
  2714.         SET 6,C         ;Z80 Z flag is bit 6
  2715.         PUSH BC
  2716. ;earlier JR comes in here
  2717.         POP AF          ;restores 6502 A and sets flags
  2718.         incPC
  2719.  
  2720.  
  2721.         ORG OP138
  2722. ;TXA - transfer X to A
  2723. ;sets Z and N flags
  2724. txa:
  2725.         DB $FD
  2726.         LD A,L
  2727.         INC A
  2728.         DEC A
  2729.         incPC
  2730.  
  2731.         ORG OP139
  2732.         JP illegal
  2733.  
  2734.         ORG OP140
  2735. styA:
  2736.         EX AF,AF'
  2737.         getabsolute_write
  2738.         EX AF,AF'
  2739.         opSTY
  2740.         incPC
  2741.  
  2742.         ORG OP141
  2743. staA:
  2744.         EX AF,AF'
  2745.         getabsolute_write
  2746.         EX AF,AF'
  2747.         opSTA
  2748.         incPC
  2749.  
  2750.         ORG OP142
  2751. stxA:
  2752.         EX AF,AF'
  2753.         getabsolute_write
  2754.         EX AF,AF'
  2755.         opSTX
  2756.         incPC
  2757.  
  2758.         ORG OP143
  2759.         JP illegal
  2760.  
  2761.         ORG OP144
  2762. bcc:
  2763.         INC DE
  2764.         JR C,bcc2
  2765.         EX AF,AF'
  2766.         nextbyteB
  2767.         LD L,(HL)
  2768.         LD A,L
  2769.         RLCA
  2770.         SBC A,A
  2771.         LD H,A
  2772.         ADD HL,DE       ;add displacement to PC (DE)
  2773.         EX DE,HL
  2774.         EX AF,AF'
  2775. bcc2:
  2776.         incPC
  2777.  
  2778.         ORG OP145
  2779. sta_zp_y:
  2780.         EX AF,AF'
  2781.         indirectY_write
  2782.         EX AF,AF'
  2783.         opSTA
  2784.         incPC
  2785.  
  2786.         ORG OP146
  2787. sta_zp:
  2788.         get_ZP_write
  2789.         opSTA
  2790.         incPC
  2791.  
  2792.         ORG OP147
  2793.         JP illegal
  2794.  
  2795.         ORG OP148
  2796. styzpx:
  2797.         EX AF,AF'
  2798.         getZPX_write
  2799.         EX AF,AF'
  2800.         opSTY
  2801.         incPC
  2802.  
  2803.         ORG OP149
  2804. stazpx:
  2805.         EX AF,AF'
  2806.         getZPX_write
  2807.         EX AF,AF'
  2808.         opSTA
  2809.         incPC
  2810.  
  2811.         ORG OP150
  2812. stxzpy:
  2813.         EX AF,AF'
  2814.         getZPY_write
  2815.         EX AF,AF'
  2816.         opSTX
  2817.         incPC
  2818.  
  2819.         ORG OP151
  2820.         JP illegal
  2821.  
  2822.         ORG OP152
  2823. ;TYA - transfer Y to A
  2824. ;sets Z and N flags
  2825. tya:
  2826.         DB $FD
  2827.         LD A,H
  2828.         INC A
  2829.         DEC A
  2830.         incPC
  2831.  
  2832.         ORG OP153
  2833. staay:
  2834.         EX AF,AF'
  2835.         getabsoluteY_write
  2836.         EX AF,AF'
  2837.         opSTA
  2838.         incPC
  2839.  
  2840.         ORG OP154
  2841. ;TXS - transfer SP to X
  2842. ;doesn't set any flags (unlike TSX)
  2843. txs:
  2844.         EXX
  2845.         DB $FD
  2846.         LD E,L
  2847.         EXX
  2848.         incPC
  2849.  
  2850.         ORG OP155
  2851.         JP illegal
  2852.  
  2853.         ORG OP156
  2854. stzA:
  2855.         EX AF,AF'
  2856.         getabsolute_write
  2857.         EX AF,AF'
  2858.         opSTZ
  2859.         incPC
  2860.  
  2861.         ORG OP157
  2862. staax:
  2863.         EX AF,AF'
  2864.         getabsoluteX_write
  2865.         EX AF,AF'
  2866.         opSTA
  2867.         incPC
  2868.  
  2869.         ORG OP158
  2870. stzax:
  2871.         EX AF,AF'
  2872.         getabsoluteX_write
  2873.         EX AF,AF'
  2874.         opSTZ
  2875.         incPC
  2876.  
  2877.         ORG OP159
  2878.         JP illegal
  2879.  
  2880.         ORG OP160
  2881. ldy_imm:
  2882.         nextbyte
  2883.         opLDY
  2884.         incPC
  2885.  
  2886.         ORG OP161
  2887. lda_zpx:
  2888.         EX AF,AF'
  2889.         indirectX_read
  2890.         EX AF,AF'
  2891.         opLDA
  2892.         incPC
  2893.  
  2894.         ORG OP162
  2895. ldx_imm:
  2896.         nextbyte
  2897.         opLDX
  2898.         incPC
  2899.        
  2900.         ORG OP163
  2901.         JP illegal
  2902.  
  2903.         ORG OP164
  2904. ldyzp:
  2905.         getZP_read
  2906.         opLDY
  2907.         incPC
  2908.  
  2909.         ORG OP165
  2910. ldazp:
  2911.         getZP_read
  2912.         opLDA
  2913.         incPC
  2914.  
  2915.         ORG OP166
  2916. ldxzp:
  2917.         getZP_read
  2918.         opLDX
  2919.         incPC
  2920.  
  2921.         ORG OP167
  2922.         JP illegal
  2923.  
  2924.         ORG OP168
  2925. ;TAY - transfer A to Y
  2926. ;sets Z and N flags
  2927. tay:
  2928.         INC A
  2929.         DEC A
  2930.         DB $FD
  2931.         LD H,A
  2932.         incPC
  2933.  
  2934.         ORG OP169
  2935. ;op173 starts very soon after op169!
  2936. lda_imm:
  2937.         nextbyte
  2938.         opLDA
  2939.         incPC
  2940.  
  2941.         ORG OP170
  2942. ;TAX - transfer A to X
  2943. ;sets Z and N flags
  2944. tax:
  2945.         INC A
  2946.         DEC A
  2947.         DB $FD
  2948.         LD L,A
  2949.         incPC
  2950.  
  2951.         ORG OP171
  2952.         JP illegal
  2953.  
  2954.         ORG OP172
  2955. ldyA:
  2956.         EX AF,AF'
  2957.         getabsolute_read
  2958.         EX AF,AF'
  2959.         opLDY
  2960.         incPC
  2961.  
  2962.         ORG OP173
  2963. ldaA:
  2964.         EX AF,AF'
  2965.         getabsolute_read
  2966.         EX AF,AF'
  2967.         opLDA
  2968.         incPC
  2969.  
  2970.         ORG OP174
  2971. ldxA:
  2972.         EX AF,AF'
  2973.         getabsolute_read
  2974.         EX AF,AF'
  2975.         opLDX
  2976.         incPC
  2977.  
  2978.         ORG OP175
  2979.         JP illegal
  2980.  
  2981.         ORG OP176
  2982. bcs:
  2983.         INC DE
  2984.         JR NC,bcs2
  2985.         EX AF,AF'
  2986.         nextbyteB
  2987.         LD L,(HL)       ;better to do this after checking flag - not before!
  2988.         LD A,L
  2989.         RLCA
  2990.         SBC A,A
  2991.         LD H,A
  2992.         ADD HL,DE       ;add displacement to PC (DE)
  2993.         EX DE,HL
  2994.         EX AF,AF'
  2995. bcs2:
  2996.         incPC
  2997.  
  2998.  
  2999.         ORG OP177
  3000. lda_zp_y:
  3001.         EX AF,AF'
  3002.         indirectY_read
  3003.         EX AF,AF'
  3004.         opLDA
  3005.         incPC
  3006.  
  3007.         ORG OP178
  3008. lda_zp:
  3009.         EX AF,AF'
  3010.         get_ZP_read
  3011.         EX AF,AF'
  3012.         opLDA
  3013.         incPC
  3014.  
  3015.         ORG OP179
  3016.         JP illegal
  3017.  
  3018.         ORG OP180
  3019. ldyzpx:
  3020.         EX AF,AF'
  3021.         getZPX_read
  3022.         EX AF,AF'
  3023.         opLDY
  3024.         incPC
  3025.  
  3026.         ORG OP181
  3027. ldazpx:
  3028.         EX AF,AF'
  3029.         getZPX_read
  3030.         EX AF,AF'
  3031.         opLDA
  3032.         incPC
  3033.  
  3034.         ORG OP182
  3035. ldxzpy:
  3036.         EX AF,AF'
  3037.         getZPY_read
  3038.         EX AF,AF'
  3039.         opLDX
  3040.         incPC
  3041.  
  3042.         ORG OP183
  3043.         JP illegal
  3044.  
  3045.         ORG OP184
  3046. clv:
  3047.         LD HL,vVflag
  3048.         LD (HL),$00
  3049.         incPC
  3050.  
  3051.         ORG OP185
  3052. ldaay:
  3053.         EX AF,AF'
  3054.         getabsoluteY_read
  3055.         EX AF,AF'
  3056.         opLDA
  3057.         incPC
  3058.  
  3059.         ORG OP186
  3060. ;TSX - transfer SP to X
  3061. ;sets Z and N flags
  3062. tsx:
  3063.         EXX
  3064.         DB $FD
  3065.         LD L,E
  3066.         INC E           ;quicker to INC E then to transfer A into A' and INC that
  3067.         DEC E
  3068.         EXX
  3069.         incPC
  3070.  
  3071.         ORG OP187
  3072.         JP illegal
  3073.  
  3074.         ORG OP188
  3075. ldyax:
  3076.         EX AF,AF'
  3077.         getabsoluteX_read
  3078.         EX AF,AF'
  3079.         opLDY
  3080.         incPC
  3081.  
  3082.         ORG OP189
  3083. ldaax:
  3084.         EX AF,AF'
  3085.         getabsoluteX_read
  3086.         EX AF,AF'
  3087.         opLDA
  3088.         incPC
  3089.  
  3090.         ORG OP190
  3091. ldxay:
  3092.         EX AF,AF'
  3093.         getabsoluteY_read
  3094.         EX AF,AF'
  3095.         opLDX
  3096.         incPC
  3097.  
  3098.         ORG OP191
  3099.         JP illegal
  3100.  
  3101.         ORG OP192
  3102. cpy_imm:
  3103.         nextbyte
  3104.         opCPY
  3105.         incPC
  3106.  
  3107.         ORG OP193
  3108. cmp_zpx:
  3109.         EX AF,AF'
  3110.         indirectX_read
  3111.         EX AF,AF'
  3112.         opCMP
  3113.         incPC
  3114.  
  3115.         ORG OP194
  3116.         JP illegal2
  3117.  
  3118.         ORG OP195
  3119.         JP illegal
  3120. ;or use alternative opcode "ostrap"
  3121. ;it allows seamless merging of 6502 and Z80 code
  3122. ;use as $C3 lsb msb to call your Z80 code from 6502
  3123. ;and finish Z80 code with call to 'rts' routine
  3124. ;
  3125. ;ostrap:
  3126. ;       nextbyte
  3127. ;       LD C,(HL)
  3128. ;       nextbyte2
  3129. ;       LD H,(HL)
  3130. ;       LD L,C
  3131. ;       JP (HL)         ;yikes!!
  3132.  
  3133.         ORG OP196
  3134. cpyzp:
  3135.         getZP_read
  3136.         opCPY
  3137.         incPC
  3138.  
  3139.         ORG OP197
  3140. cmpzp:
  3141.         getZP_read
  3142.         opCMP
  3143.         incPC
  3144.  
  3145.         ORG OP198
  3146. deczp:
  3147.         getZP_read
  3148.         opDEC
  3149.         incPC
  3150.  
  3151.         ORG OP199
  3152.         JP illegal
  3153.  
  3154.         ORG OP200
  3155. iny:    DB $FD
  3156.         INC H
  3157. ;flags set correctly by INC instruction in this case
  3158.         incPC
  3159.  
  3160.         ORG OP201
  3161. cmp_imm:
  3162.         nextbyte
  3163.         opCMP
  3164.         incPC
  3165.  
  3166.         ORG OP202
  3167. dex:    DB $FD
  3168.         DEC L
  3169. ;flags set correctly by DEC instruction in this case
  3170.         incPC
  3171.  
  3172.         ORG OP203
  3173. wai:
  3174.         incPC           ;do nothing for now!
  3175.  
  3176.         ORG OP204
  3177. cpyA:
  3178.         EX AF,AF'
  3179.         getabsolute_read
  3180.         EX AF,AF'
  3181.         opCPY
  3182.         incPC
  3183.  
  3184.         ORG OP205
  3185. cmpA:
  3186.         EX AF,AF'
  3187.         getabsolute_read
  3188.         EX AF,AF'
  3189.         opCMP
  3190.         incPC
  3191.  
  3192.         ORG OP206
  3193. decA:
  3194.         EX AF,AF'
  3195.         getabsolute_read
  3196.         EX AF,AF'
  3197.         opDEC
  3198.         incPC
  3199.  
  3200.         ORG OP207
  3201.         JP illegal
  3202.  
  3203.         ORG OP208
  3204. bne:
  3205.         INC DE
  3206.         JR Z,bne2
  3207.         EX AF,AF'
  3208.         nextbyteB
  3209.         LD L,(HL)
  3210.         LD A,L
  3211.         RLCA
  3212.         SBC A,A
  3213.         LD H,A
  3214.         ADD HL,DE       ;add displacement to PC (DE)
  3215.         EX DE,HL
  3216.         EX AF,AF'
  3217. bne2:
  3218.         incPC
  3219.  
  3220.         ORG OP209
  3221. cmp_zp_y:
  3222.         EX AF,AF'
  3223.         indirectY_read
  3224.         EX AF,AF'
  3225.         opCMP
  3226.         incPC
  3227.  
  3228.         ORG OP210
  3229. cmp_zp:
  3230.         get_ZP_read
  3231.         opCMP
  3232.         incPC
  3233.  
  3234.         ORG OP211
  3235.         JP illegal
  3236.  
  3237.         ORG OP212
  3238.         JP illegal2
  3239.  
  3240.         ORG OP213
  3241. cmpzpx:
  3242.         EX AF,AF'
  3243.         getZPX_read
  3244.         EX AF,AF'
  3245.         opCMP  
  3246.         incPC
  3247.  
  3248.         ORG OP214
  3249. deczpx:
  3250.         EX AF,AF'
  3251.         getZPX_read
  3252.         EX AF,AF'
  3253.         opDEC
  3254.         incPC
  3255.  
  3256.         ORG OP215
  3257.         JP illegal
  3258.  
  3259.         ORG OP216
  3260. cld:
  3261.         LD HL,vXflag
  3262.         RES 3,(HL)      ;clear D bit
  3263. cld2:
  3264.         LD HL,adcdaa2
  3265.         LD (HL),$00     ;set these routines to NOP (opcode 00) instead of DAA
  3266.         LD HL,sbcdaa2
  3267.         LD (HL),$00     ;preserve flags
  3268.         incPC
  3269.  
  3270.         ORG OP217
  3271. cmpay:
  3272.         EX AF,AF'
  3273.         getabsoluteY_read
  3274.         EX AF,AF'
  3275.         opCMP
  3276.         incPC
  3277.  
  3278.         ORG OP218
  3279. ;PHX - push X
  3280. ;no flags affected
  3281. phx:
  3282.         EXX
  3283.         EX AF,AF'
  3284.         DB $FD
  3285.         LD A,L
  3286.         LD (DE),A
  3287.         DEC E           ;SP is 0100-01FF only
  3288.         EX AF,AF'
  3289.         EXX
  3290.         incPC
  3291.  
  3292.         ORG OP219
  3293. stp:
  3294.         incPC           ;do nothing for now!
  3295.  
  3296.         ORG OP220
  3297.         JP illegal3
  3298.  
  3299.         ORG OP221
  3300. cmpax:
  3301.         EX AF,AF'
  3302.         getabsoluteX_read
  3303.         EX AF,AF'
  3304.         opCMP
  3305.         incPC
  3306.  
  3307.         ORG OP222
  3308. decax:
  3309.         EX AF,AF'
  3310.         getabsoluteX_read
  3311.         EX AF,AF'
  3312.         opDEC
  3313.         incPC
  3314.        
  3315.         ORG OP223
  3316.         JP illegal
  3317.  
  3318.         ORG OP224
  3319. cpx_imm:
  3320.         nextbyte
  3321.         opCPX
  3322.         incPC
  3323.  
  3324.         ORG OP225
  3325. sbc_zpx:
  3326.         EX AF,AF'
  3327.         indirectX_read
  3328.         EX AF,AF'
  3329.         opSBC
  3330.         incPC
  3331.  
  3332.         ORG OP226
  3333.         JP illegal2
  3334.  
  3335.         ORG OP227
  3336.         JP illegal
  3337.  
  3338.         ORG OP228
  3339. cpxzp:
  3340.         getZP_read
  3341.         opCPX
  3342.         incPC
  3343.  
  3344.         ORG OP229
  3345. sbczp:
  3346.         getZP_read
  3347.         opSBC
  3348.         incPC
  3349.  
  3350.         ORG OP230
  3351. inczp:
  3352.         getZP_read
  3353.         opINC
  3354.         incPC
  3355.  
  3356.         ORG OP231
  3357.         JP illegal
  3358.  
  3359.         ORG OP232
  3360. inx:    DB $FD
  3361.         INC L
  3362. ;flags set correctly by INC instruction in this case
  3363.         incPC
  3364.  
  3365.         ORG OP233
  3366. sbc_imm:
  3367.         nextbyte
  3368.  
  3369. sharedsbc2:
  3370. ;same comments as ADC for reasons of shared routine
  3371. ;
  3372. ;SBC on 6502 is quite different to Z80!
  3373. ;it is effectively A-operand-(1-CF)
  3374. ;so complement CF flag first!
  3375.         CCF
  3376.         SBC A,(HL)
  3377.  
  3378. ;the following byte is modified by SED and CLD instructions
  3379. ;to either NOP (CLD) or DAA (SED)
  3380.  
  3381. ;and result of CF flag is opposite to Z80 too!
  3382. sbcdaa2:
  3383.         DAA ;patch daa/nop
  3384.  
  3385. ;and result of CF flag is opposite to Z80 too!
  3386.         CCF
  3387.         LD HL,vVflag
  3388.         JP PO,$+8
  3389. ;jump if overflow unset
  3390. ;A=$40 if V set, A=0 if V reset
  3391.         LD (HL),$40
  3392.         incPC
  3393. ;no overflow comes here
  3394.         LD (HL),$00
  3395.         incPC
  3396.  
  3397.         ORG OP234
  3398. nop:
  3399.         incPC           ;do nothing!
  3400.  
  3401.         ORG OP235
  3402.         JP illegal
  3403.  
  3404.         ORG OP236
  3405. cpxA:
  3406.         EX AF,AF'
  3407.         getabsolute_read
  3408.         EX AF,AF'
  3409.         opCPX
  3410.         incPC
  3411.  
  3412.         ORG OP237
  3413. sbcA:
  3414.         EX AF,AF'
  3415.         getabsolute_read
  3416.         EX AF,AF'
  3417.         opSBC
  3418.         incPC
  3419.  
  3420.         ORG OP238
  3421. incA:
  3422.         EX AF,AF'
  3423.         getabsolute_read
  3424.         EX AF,AF'
  3425.         opINC
  3426.         incPC
  3427.  
  3428.         ORG OP239
  3429.         JP illegal
  3430.  
  3431.         ORG OP240
  3432. beq:
  3433.         INC DE
  3434.         JR NZ,beq2
  3435.         EX AF,AF'
  3436.         nextbyteB
  3437.         LD L,(HL)
  3438.         LD A,L
  3439.         RLCA
  3440.         SBC A,A
  3441.         LD H,A
  3442.         ADD HL,DE       ;add displacement to PC (DE)
  3443.         EX DE,HL
  3444.         EX AF,AF'
  3445. beq2:
  3446.         incPC
  3447.  
  3448.         ORG OP241
  3449. sbc_zp_y:
  3450.         EX AF,AF'
  3451.         indirectY_read
  3452.         EX AF,AF'
  3453.         opSBC
  3454.         incPC
  3455.  
  3456.         ORG OP242
  3457. sbc_zp:
  3458.         get_ZP_read
  3459.         opSBC
  3460.         incPC
  3461.  
  3462.         ORG OP243
  3463.         JP illegal
  3464.  
  3465.         ORG OP244
  3466.         JP illegal2
  3467.  
  3468.         ORG OP245
  3469. sbczpx:
  3470.         EX AF,AF'
  3471.         getZPX_read
  3472.         EX AF,AF'
  3473.         opSBC
  3474.         incPC
  3475.  
  3476.         ORG OP246
  3477. inczpx:
  3478.         EX AF,AF'
  3479.         getZPX_read
  3480.         EX AF,AF'
  3481.         opINC
  3482.         incPC
  3483.  
  3484.         ORG OP247
  3485.         JP illegal
  3486.  
  3487.         ORG OP248
  3488. sed:
  3489.         LD HL,vXflag
  3490.         SET 3,(HL)      ;set D bit
  3491. sed2:
  3492.         LD HL,adcdaa2
  3493.         LD (HL),$27     ;set these routines to DAA (opcode 27) instead of NOP
  3494.         LD HL,sbcdaa2
  3495.         LD (HL),$27     ;preserve flags
  3496.         incPC
  3497.  
  3498.         ORG OP249
  3499. sbcay:
  3500.         EX AF,AF'
  3501.         getabsoluteY_read
  3502.         EX AF,AF'
  3503.         opSBC
  3504.         incPC
  3505.  
  3506.         ORG OP250
  3507. ;PLX - pull X
  3508. ;sets Z and N flags
  3509. plx:
  3510.         EXX
  3511.         EX AF,AF'
  3512.         INC E
  3513.         LD A,(DE)
  3514.         LD B,A
  3515.         EXX
  3516.         EX AF,AF'
  3517.         INC B
  3518.         DEC B
  3519.         DB $FD
  3520.         LD L,B
  3521.         incPC
  3522.  
  3523.         ORG OP251
  3524.         JP illegal
  3525.  
  3526.         ORG OP252
  3527.         JP illegal3
  3528.  
  3529.         ORG OP253
  3530. sbcax:
  3531.         EX AF,AF'
  3532.         getabsoluteX_read
  3533.         EX AF,AF'
  3534.         opSBC
  3535.         incPC
  3536.  
  3537.         ORG OP254
  3538. incax:
  3539.         EX AF,AF'
  3540.         getabsoluteX_read
  3541.         EX AF,AF'
  3542.         opINC
  3543.         incPC
  3544.  
  3545.         ORG OP255
  3546.         JP illegal
  3547.  
  3548.         ORG IM2page*256
  3549.  
  3550. ;this is used as an IM2 vector table so we don't care if a kempston joystick is plugged in or not!
  3551.  
  3552.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3553.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3554.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3555.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3556.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3557.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3558.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3559.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3560.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3561.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3562.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3563.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3564.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3565.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3566.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3567.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3568.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3569.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3570.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3571.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3572.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3573.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3574.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3575.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3576.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3577.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3578.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3579.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3580.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3581.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3582.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3583.         DB IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1,IM2page+1
  3584.         DB IM2page+1    ;257th byte goes here
  3585.  
  3586.  
  3587.  
  3588.  
  3589.         ORG Oppage*256
  3590.         DB OP0/256
  3591.         DB OP1/256
  3592.         DB OP2/256
  3593.         DB OP3/256
  3594.         DB OP4/256
  3595.         DB OP5/256
  3596.         DB OP6/256
  3597.         DB OP7/256
  3598.         DB OP8/256
  3599.         DB OP9/256
  3600.         DB OP10/256
  3601.         DB OP11/256
  3602.         DB OP12/256
  3603.         DB OP13/256
  3604.         DB OP14/256
  3605.         DB OP15/256
  3606.         DB OP16/256
  3607.         DB OP17/256
  3608.         DB OP18/256
  3609.         DB OP19/256
  3610.         DB OP20/256
  3611.         DB OP21/256
  3612.         DB OP22/256
  3613.         DB OP23/256
  3614.         DB OP24/256
  3615.         DB OP25/256
  3616.         DB OP26/256
  3617.         DB OP27/256
  3618.         DB OP28/256
  3619.         DB OP29/256
  3620.         DB OP30/256
  3621.         DB OP31/256
  3622.         DB OP32/256
  3623.         DB OP33/256
  3624.         DB OP34/256
  3625.         DB OP35/256
  3626.         DB OP36/256
  3627.         DB OP37/256
  3628.         DB OP38/256
  3629.         DB OP39/256
  3630.         DB OP40/256
  3631.         DB OP41/256
  3632.         DB OP42/256
  3633.         DB OP43/256
  3634.         DB OP44/256
  3635.         DB OP45/256
  3636.         DB OP46/256
  3637.         DB OP47/256
  3638.         DB OP48/256
  3639.         DB OP49/256
  3640.         DB OP50/256
  3641.         DB OP51/256
  3642.         DB OP52/256
  3643.         DB OP53/256
  3644.         DB OP54/256
  3645.         DB OP55/256
  3646.         DB OP56/256
  3647.         DB OP57/256
  3648.         DB OP58/256
  3649.         DB OP59/256
  3650.         DB OP60/256
  3651.         DB OP61/256
  3652.         DB OP62/256
  3653.         DB OP63/256
  3654.         DB OP64/256
  3655.         DB OP65/256
  3656.         DB OP66/256
  3657.         DB OP67/256
  3658.         DB OP68/256
  3659.         DB OP69/256
  3660.         DB OP70/256
  3661.         DB OP71/256
  3662.         DB OP72/256
  3663.         DB OP73/256
  3664.         DB OP74/256
  3665.         DB OP75/256
  3666.         DB OP76/256
  3667.         DB OP77/256
  3668.         DB OP78/256
  3669.         DB OP79/256
  3670.         DB OP80/256
  3671.         DB OP81/256
  3672.         DB OP82/256
  3673.         DB OP83/256
  3674.         DB OP84/256
  3675.         DB OP85/256
  3676.         DB OP86/256
  3677.         DB OP87/256
  3678.         DB OP88/256
  3679.         DB OP89/256
  3680.         DB OP90/256
  3681.         DB OP91/256
  3682.         DB OP92/256
  3683.         DB OP93/256
  3684.         DB OP94/256
  3685.         DB OP95/256
  3686.         DB OP96/256
  3687.         DB OP97/256
  3688.         DB OP98/256
  3689.         DB OP99/256
  3690.         DB OP100/256
  3691.         DB OP101/256
  3692.         DB OP102/256
  3693.         DB OP103/256
  3694.         DB OP104/256
  3695.         DB OP105/256
  3696.         DB OP106/256
  3697.         DB OP107/256
  3698.         DB OP108/256
  3699.         DB OP109/256
  3700.         DB OP110/256
  3701.         DB OP111/256
  3702.         DB OP112/256
  3703.         DB OP113/256
  3704.         DB OP114/256
  3705.         DB OP115/256
  3706.         DB OP116/256
  3707.         DB OP117/256
  3708.         DB OP118/256
  3709.         DB OP119/256
  3710.         DB OP120/256
  3711.         DB OP121/256
  3712.         DB OP122/256
  3713.         DB OP123/256
  3714.         DB OP124/256
  3715.         DB OP125/256
  3716.         DB OP126/256
  3717.         DB OP127/256
  3718.         DB OP128/256
  3719.         DB OP129/256
  3720.         DB OP130/256
  3721.         DB OP131/256
  3722.         DB OP132/256
  3723.         DB OP133/256
  3724.         DB OP134/256
  3725.         DB OP135/256
  3726.         DB OP136/256
  3727.         DB OP137/256
  3728.         DB OP138/256
  3729.         DB OP139/256
  3730.         DB OP140/256
  3731.         DB OP141/256
  3732.         DB OP142/256
  3733.         DB OP143/256
  3734.         DB OP144/256
  3735.         DB OP145/256
  3736.         DB OP146/256
  3737.         DB OP147/256
  3738.         DB OP148/256
  3739.         DB OP149/256
  3740.         DB OP150/256
  3741.         DB OP151/256
  3742.         DB OP152/256
  3743.         DB OP153/256
  3744.         DB OP154/256
  3745.         DB OP155/256
  3746.         DB OP156/256
  3747.         DB OP157/256
  3748.         DB OP158/256
  3749.         DB OP159/256
  3750.         DB OP160/256
  3751.         DB OP161/256
  3752.         DB OP162/256
  3753.         DB OP163/256
  3754.         DB OP164/256
  3755.         DB OP165/256
  3756.         DB OP166/256
  3757.         DB OP167/256
  3758.         DB OP168/256
  3759.         DB OP169/256
  3760.         DB OP170/256
  3761.         DB OP171/256
  3762.         DB OP172/256
  3763.         DB OP173/256
  3764.         DB OP174/256
  3765.         DB OP175/256
  3766.         DB OP176/256
  3767.         DB OP177/256
  3768.         DB OP178/256
  3769.         DB OP179/256
  3770.         DB OP180/256
  3771.         DB OP181/256
  3772.         DB OP182/256
  3773.         DB OP183/256
  3774.         DB OP184/256
  3775.         DB OP185/256
  3776.         DB OP186/256
  3777.         DB OP187/256
  3778.         DB OP188/256
  3779.         DB OP189/256
  3780.         DB OP190/256
  3781.         DB OP191/256
  3782.         DB OP192/256
  3783.         DB OP193/256
  3784.         DB OP194/256
  3785.         DB OP195/256
  3786.         DB OP196/256
  3787.         DB OP197/256
  3788.         DB OP198/256
  3789.         DB OP199/256
  3790.         DB OP200/256
  3791.         DB OP201/256
  3792.         DB OP202/256
  3793.         DB OP203/256
  3794.         DB OP204/256
  3795.         DB OP205/256
  3796.         DB OP206/256
  3797.         DB OP207/256
  3798.         DB OP208/256
  3799.         DB OP209/256
  3800.         DB OP210/256
  3801.         DB OP211/256
  3802.         DB OP212/256
  3803.         DB OP213/256
  3804.         DB OP214/256
  3805.         DB OP215/256
  3806.         DB OP216/256
  3807.         DB OP217/256
  3808.         DB OP218/256
  3809.         DB OP219/256
  3810.         DB OP220/256
  3811.         DB OP221/256
  3812.         DB OP222/256
  3813.         DB OP223/256
  3814.         DB OP224/256
  3815.         DB OP225/256
  3816.         DB OP226/256
  3817.         DB OP227/256
  3818.         DB OP228/256
  3819.         DB OP229/256
  3820.         DB OP230/256
  3821.         DB OP231/256
  3822.         DB OP232/256
  3823.         DB OP233/256
  3824.         DB OP234/256
  3825.         DB OP235/256
  3826.         DB OP236/256
  3827.         DB OP237/256
  3828.         DB OP238/256
  3829.         DB OP239/256
  3830.         DB OP240/256
  3831.         DB OP241/256
  3832.         DB OP242/256
  3833.         DB OP243/256
  3834.         DB OP244/256
  3835.         DB OP245/256
  3836.         DB OP246/256
  3837.         DB OP247/256
  3838.         DB OP248/256
  3839.         DB OP249/256
  3840.         DB OP250/256
  3841.         DB OP251/256
  3842.         DB OP252/256
  3843.         DB OP253/256
  3844.         DB OP254/256
  3845.         DB OP255/256
  3846.  
  3847. trap    EQU $01
  3848.  
  3849.         ORG M1page*256
  3850. ;Opcode decode table
  3851.  
  3852.         DB $80
  3853.         DB $81
  3854.         DB $82 
  3855.         DB $83  ;VIC-20 had 1/2K at start of memory!
  3856. ;3K RAM expansion table goes here!
  3857.         DB $84
  3858.         DB $85
  3859.         DB $86
  3860.         DB $87
  3861.         DB $88
  3862.         DB $89
  3863.         DB $8A
  3864.         DB $8B
  3865.         DB $8C
  3866.         DB $8D
  3867.         DB $8E
  3868.         DB $8F 
  3869. ;4K base RAM goes here
  3870.         DB $90
  3871.         DB $91
  3872.         DB $92
  3873.         DB $93
  3874.         DB $94
  3875.         DB $95
  3876.         DB $96
  3877.         DB $97
  3878.         DB $98
  3879.         DB $99
  3880.         DB $9A
  3881.         DB $9B
  3882.         DB $9C
  3883.         DB $9D
  3884.         DB $9E
  3885.         DB $9F
  3886. ;2000-7FFF unused memory
  3887.         DB $02
  3888.         DB $02
  3889.         DB $02
  3890.         DB $02
  3891.         DB $02
  3892.         DB $02
  3893.         DB $02
  3894.         DB $02
  3895.         DB $02
  3896.         DB $02
  3897.         DB $02
  3898.         DB $02
  3899.         DB $02
  3900.         DB $02
  3901.         DB $02
  3902.         DB $02
  3903.         DB $02
  3904.         DB $02
  3905.         DB $02
  3906.         DB $02
  3907.         DB $02
  3908.         DB $02
  3909.         DB $02
  3910.         DB $02
  3911.         DB $02
  3912.         DB $02
  3913.         DB $02
  3914.         DB $02
  3915.         DB $02
  3916.         DB $02
  3917.         DB $02
  3918.         DB $02
  3919.         DB $02
  3920.         DB $02
  3921.         DB $02
  3922.         DB $02
  3923.         DB $02
  3924.         DB $02
  3925.         DB $02
  3926.         DB $02
  3927.         DB $02
  3928.         DB $02
  3929.         DB $02
  3930.         DB $02
  3931.         DB $02
  3932.         DB $02
  3933.         DB $02
  3934.         DB $02
  3935.         DB $02
  3936.         DB $02
  3937.         DB $02
  3938.         DB $02
  3939.         DB $02
  3940.         DB $02
  3941.         DB $02
  3942.         DB $02
  3943.         DB $02
  3944.         DB $02
  3945.         DB $02
  3946.         DB $02
  3947.         DB $02
  3948.         DB $02
  3949.         DB $02
  3950.         DB $02
  3951.         DB $02
  3952.         DB $02
  3953.         DB $02
  3954.         DB $02
  3955.         DB $02
  3956.         DB $02
  3957.         DB $02
  3958.         DB $02
  3959.         DB $02
  3960.         DB $02
  3961.         DB $02
  3962.         DB $02
  3963.         DB $02
  3964.         DB $02
  3965.         DB $02
  3966.         DB $02
  3967.         DB $02
  3968.         DB $02
  3969.         DB $02
  3970.         DB $02
  3971.         DB $02
  3972.         DB $02
  3973.         DB $02
  3974.         DB $02
  3975.         DB $02
  3976.         DB $02
  3977.         DB $02
  3978.         DB $02
  3979.         DB $02
  3980.         DB $02
  3981.         DB $02
  3982.         DB $02
  3983. ;character bit maps now (A000-AFFF)
  3984.         DB $A0
  3985.         DB $A1
  3986.         DB $A2
  3987.         DB $A3
  3988.         DB $A4
  3989.         DB $A5
  3990.         DB $A6
  3991.         DB $A7
  3992.         DB $A8
  3993.         DB $A9
  3994.         DB $AA
  3995.         DB $AB
  3996.         DB $AC
  3997.         DB $AD
  3998.         DB $AE
  3999.         DB $AF
  4000. ;VIC chip (9000-93FF)
  4001.         DB $02  ;can't execute VIC registers!
  4002.         DB $02
  4003.         DB $02
  4004.         DB $02
  4005. ;alternate colour nybble
  4006.         DB colourram+1          ;you can run code in nybble area if you want!
  4007.         DB colourram+2
  4008. ;main colour nybble (in unexpanded VIC) (9600-97FF)
  4009.         DB colourram+1
  4010.         DB colourram+2
  4011. ;more possible expansion RAM (9800-BFFF)
  4012.         DB $02
  4013.         DB $02
  4014.         DB $02
  4015.         DB $02
  4016.         DB $02
  4017.         DB $02
  4018.         DB $02
  4019.         DB $02
  4020. ;CARTRIDGE AREA $A000-$BFFF
  4021.         DB $20
  4022.         DB $21
  4023.         DB $22
  4024.         DB $23
  4025.         DB $24
  4026.         DB $25
  4027.         DB $26
  4028.         DB $27
  4029.         DB $28
  4030.         DB $29
  4031.         DB $2A
  4032.         DB $2B
  4033.         DB $2C
  4034.         DB $2D
  4035.         DB $2E
  4036.         DB $2F
  4037.         DB $30
  4038.         DB $31
  4039.         DB $32
  4040.         DB $33
  4041.         DB $34
  4042.         DB $35
  4043.         DB $36
  4044.         DB $37
  4045.         DB $38
  4046.         DB $39
  4047.         DB $3A
  4048.         DB $3B
  4049.         DB $3C
  4050.         DB $3D
  4051.         DB $3E
  4052.         DB $3F
  4053. ;BASIC2 ROM C000-DFFF
  4054.         DB $E0
  4055.         DB $E1
  4056.         DB $E2
  4057.         DB $E3
  4058.         DB $E4
  4059.         DB $E5
  4060.         DB $E6
  4061.         DB $E7
  4062.         DB $E8
  4063.         DB $E9
  4064.         DB $EA
  4065.         DB $EB
  4066.         DB $EC
  4067.         DB $ED
  4068.         DB $EE
  4069.         DB $EF
  4070.         DB $F0
  4071.         DB $F1
  4072.         DB $F2
  4073.         DB $F3
  4074.         DB $F4
  4075.         DB $F5
  4076.         DB $F6
  4077.         DB $F7
  4078.         DB $F8
  4079.         DB $F9
  4080.         DB $FA
  4081.         DB $FB
  4082.         DB $FC
  4083.         DB $FD
  4084.         DB $FE
  4085.         DB $FF
  4086. ;KERNAL ROM E000-FFFF
  4087.         DB $60
  4088.         DB $61
  4089.         DB $62
  4090.         DB $63
  4091.         DB $64
  4092.         DB $65
  4093.         DB $66
  4094.         DB $67
  4095.         DB $68
  4096.         DB $69
  4097.         DB $6A
  4098.         DB $6B
  4099.         DB $6C
  4100.         DB $6D
  4101.         DB $6E
  4102.         DB $6F
  4103.         DB $70
  4104.         DB $71
  4105.         DB $72
  4106.         DB $73
  4107.         DB $74
  4108.         DB $75
  4109.         DB $76
  4110.         DB $77
  4111.         DB $78
  4112.         DB $79
  4113.         DB $7A
  4114.         DB $7B
  4115.         DB $7C
  4116.         DB $7D
  4117.         DB $7E
  4118.         DB $7F
  4119.  
  4120. ;*** MEMORY READ TABLE ***
  4121. ;MRpage
  4122.         DB $81
  4123.         DB $82 
  4124.         DB $83  ;VIC-20 had 1/2K at start of memory!
  4125.         DB $84
  4126. ;3K RAM expansion table goes here!
  4127.         DB $85
  4128.         DB $86
  4129.         DB $87
  4130.         DB $88
  4131.         DB $89
  4132.         DB $8A
  4133.         DB $8B
  4134.         DB $8C
  4135.         DB $8D
  4136.         DB $8E
  4137.         DB $8F 
  4138.         DB $90
  4139. ;4K base RAM goes here
  4140.         DB $91
  4141.         DB $92
  4142.         DB $93
  4143.         DB $94
  4144.         DB $95
  4145.         DB $96
  4146.         DB $97
  4147.         DB $98
  4148.         DB $99
  4149.         DB $9A
  4150.         DB $9B
  4151.         DB $9C
  4152.         DB $9D
  4153.         DB $9E
  4154.         DB $9F
  4155.         DB $A0
  4156. ;2000-7FFF unused memory
  4157.         DB $02
  4158.         DB $02
  4159.         DB $02
  4160.         DB $02
  4161.         DB $02
  4162.         DB $02
  4163.         DB $02
  4164.         DB $02
  4165.         DB $02
  4166.         DB $02
  4167.         DB $02
  4168.         DB $02
  4169.         DB $02
  4170.         DB $02
  4171.         DB $02
  4172.         DB $02
  4173.         DB $02
  4174.         DB $02
  4175.         DB $02
  4176.         DB $02
  4177.         DB $02
  4178.         DB $02
  4179.         DB $02
  4180.         DB $02
  4181.         DB $02
  4182.         DB $02
  4183.         DB $02
  4184.         DB $02
  4185.         DB $02
  4186.         DB $02
  4187.         DB $02
  4188.         DB $02
  4189.         DB $02
  4190.         DB $02
  4191.         DB $02
  4192.         DB $02
  4193.         DB $02
  4194.         DB $02
  4195.         DB $02
  4196.         DB $02
  4197.         DB $02
  4198.         DB $02
  4199.         DB $02
  4200.         DB $02
  4201.         DB $02
  4202.         DB $02
  4203.         DB $02
  4204.         DB $02
  4205.         DB $02
  4206.         DB $02
  4207.         DB $02
  4208.         DB $02
  4209.         DB $02
  4210.         DB $02
  4211.         DB $02
  4212.         DB $02
  4213.         DB $02
  4214.         DB $02
  4215.         DB $02
  4216.         DB $02
  4217.         DB $02
  4218.         DB $02
  4219.         DB $02
  4220.         DB $02
  4221.         DB $02
  4222.         DB $02
  4223.         DB $02
  4224.         DB $02
  4225.         DB $02
  4226.         DB $02
  4227.         DB $02
  4228.         DB $02
  4229.         DB $02
  4230.         DB $02
  4231.         DB $02
  4232.         DB $02
  4233.         DB $02
  4234.         DB $02
  4235.         DB $02
  4236.         DB $02
  4237.         DB $02
  4238.         DB $02
  4239.         DB $02
  4240.         DB $02
  4241.         DB $02
  4242.         DB $02
  4243.         DB $02
  4244.         DB $02
  4245.         DB $02
  4246.         DB $02
  4247.         DB $02
  4248.         DB $02
  4249.         DB $02
  4250.         DB $02
  4251.         DB $02
  4252.         DB $02
  4253. ;character bit maps now (A000-AFFF)
  4254.         DB $A1
  4255.         DB $A2
  4256.         DB $A3
  4257.         DB $A4
  4258.         DB $A5
  4259.         DB $A6
  4260.         DB $A7
  4261.         DB $A8
  4262.         DB $A9
  4263.         DB $AA
  4264.         DB $AB
  4265.         DB $AC
  4266.         DB $AD
  4267.         DB $AE
  4268.         DB $AF
  4269.         DB $B0
  4270. ;VIC chip (9000-93FF)
  4271.         DB trap         ;VIC chip
  4272.         DB trap         ;VIA chip
  4273.         DB $02
  4274.         DB $02
  4275. ;alternate colour nybble
  4276.         DB colourram+1
  4277.         DB colourram+2
  4278. ;main colour nybble (in unexpanded VIC) (9600-97FF)
  4279.         DB colourram+1
  4280.         DB colourram+2
  4281. ;more possible expansion RAM (9800-BFFF)
  4282.         DB $02
  4283.         DB $02
  4284.         DB $02
  4285.         DB $02
  4286.         DB $02
  4287.         DB $02
  4288.         DB $02
  4289.         DB $02
  4290. ;CARTRIDGE AREA $A000-$BFFF
  4291.         DB $21
  4292.         DB $22
  4293.         DB $23
  4294.         DB $24
  4295.         DB $25
  4296.         DB $26
  4297.         DB $27
  4298.         DB $28
  4299.         DB $29
  4300.         DB $2A
  4301.         DB $2B
  4302.         DB $2C
  4303.         DB $2D
  4304.         DB $2E
  4305.         DB $2F
  4306.         DB $30
  4307.         DB $31
  4308.         DB $32
  4309.         DB $33
  4310.         DB $34
  4311.         DB $35
  4312.         DB $36
  4313.         DB $37
  4314.         DB $38
  4315.         DB $39
  4316.         DB $3A
  4317.         DB $3B
  4318.         DB $3C
  4319.         DB $3D
  4320.         DB $3E
  4321.         DB $3F
  4322.         DB $40
  4323. ;BASIC2 ROM C000-DFFF
  4324.         DB $E1
  4325.         DB $E2
  4326.         DB $E3
  4327.         DB $E4
  4328.         DB $E5
  4329.         DB $E6
  4330.         DB $E7
  4331.         DB $E8
  4332.         DB $E9
  4333.         DB $EA
  4334.         DB $EB
  4335.         DB $EC
  4336.         DB $ED
  4337.         DB $EE
  4338.         DB $EF
  4339.         DB $F0
  4340.         DB $F1
  4341.         DB $F2
  4342.         DB $F3
  4343.         DB $F4
  4344.         DB $F5
  4345.         DB $F6
  4346.         DB $F7
  4347.         DB $F8
  4348.         DB $F9
  4349.         DB $FA
  4350.         DB $FB
  4351.         DB $FC
  4352.         DB $FD
  4353.         DB $FE
  4354.         DB $FF
  4355.         DB $00  ;this really should be $00 so it wraps around to $FF
  4356. ;KERNAL ROM E000-FFFF
  4357.         DB $61
  4358.         DB $62
  4359.         DB $63
  4360.         DB $64
  4361.         DB $65
  4362.         DB $66
  4363.         DB $67
  4364.         DB $68
  4365.         DB $69
  4366.         DB $6A
  4367.         DB $6B
  4368.         DB $6C
  4369.         DB $6D
  4370.         DB $6E
  4371.         DB $6F
  4372.         DB $70
  4373.         DB $71
  4374.         DB $72
  4375.         DB $73
  4376.         DB $74
  4377.         DB $75
  4378.         DB $76
  4379.         DB $77
  4380.         DB $78
  4381.         DB $79
  4382.         DB $7A
  4383.         DB $7B
  4384.         DB $7C
  4385.         DB $7D
  4386.         DB $7E
  4387.         DB $7F
  4388.         DB $80
  4389.  
  4390. ;*** MEMORY WRITE TABLE ***
  4391. ;MWpage
  4392.         DB $81
  4393.         DB $82 
  4394.         DB $83  ;VIC-20 had 1/2K at start of memory!
  4395.         DB $84
  4396. ;3K RAM expansion table goes here!
  4397.         DB $85
  4398.         DB $86
  4399.         DB $87
  4400.         DB $88
  4401.         DB $89
  4402.         DB $8A
  4403.         DB $8B
  4404.         DB $8C
  4405.         DB $8D
  4406.         DB $8E
  4407.         DB $8F 
  4408.         DB $90
  4409. ;4K base RAM goes here
  4410.         DB $91
  4411.         DB $92
  4412.         DB $93
  4413.         DB $94
  4414.         DB $95
  4415.         DB $96
  4416.         DB $97
  4417.         DB $98
  4418.         DB $99
  4419.         DB $9A
  4420.         DB $9B
  4421.         DB $9C
  4422.         DB $9D
  4423.         DB $9E
  4424.         DB $9F          ;trap writes to screen done via VIC9005!
  4425.         DB $A0
  4426. ;2000-7FFF unused memory
  4427.         DB $02
  4428.         DB $02
  4429.         DB $02
  4430.         DB $02
  4431.         DB $02
  4432.         DB $02
  4433.         DB $02
  4434.         DB $02
  4435.         DB $02
  4436.         DB $02
  4437.         DB $02
  4438.         DB $02
  4439.         DB $02
  4440.         DB $02
  4441.         DB $02
  4442.         DB $02
  4443.         DB $02
  4444.         DB $02
  4445.         DB $02
  4446.         DB $02
  4447.         DB $02
  4448.         DB $02
  4449.         DB $02
  4450.         DB $02
  4451.         DB $02
  4452.         DB $02
  4453.         DB $02
  4454.         DB $02
  4455.         DB $02
  4456.         DB $02
  4457.         DB $02
  4458.         DB $02
  4459.         DB $02  ;set this to $03 if you want +8K RAM
  4460.         DB $02
  4461.         DB $02
  4462.         DB $02
  4463.         DB $02
  4464.         DB $02
  4465.         DB $02
  4466.         DB $02
  4467.         DB $02
  4468.         DB $02
  4469.         DB $02
  4470.         DB $02
  4471.         DB $02
  4472.         DB $02
  4473.         DB $02
  4474.         DB $02
  4475.         DB $02
  4476.         DB $02
  4477.         DB $02
  4478.         DB $02
  4479.         DB $02
  4480.         DB $02
  4481.         DB $02
  4482.         DB $02
  4483.         DB $02
  4484.         DB $02
  4485.         DB $02
  4486.         DB $02
  4487.         DB $02
  4488.         DB $02
  4489.         DB $02
  4490.         DB $02
  4491.         DB $02
  4492.         DB $02
  4493.         DB $02
  4494.         DB $02
  4495.         DB $02
  4496.         DB $02
  4497.         DB $02
  4498.         DB $02
  4499.         DB $02
  4500.         DB $02
  4501.         DB $02
  4502.         DB $02
  4503.         DB $02
  4504.         DB $02
  4505.         DB $02
  4506.         DB $02
  4507.         DB $02
  4508.         DB $02
  4509.         DB $02
  4510.         DB $02
  4511.         DB $02
  4512.         DB $02
  4513.         DB $02
  4514.         DB $02
  4515.         DB $02
  4516.         DB $02
  4517.         DB $02
  4518.         DB $02
  4519.         DB $02
  4520.         DB $02
  4521.         DB $02
  4522.         DB $02
  4523. ;character bit maps (A000-AFFF)
  4524.         DB $02
  4525.         DB $02
  4526.         DB $02
  4527.         DB $02
  4528.         DB $02
  4529.         DB $02
  4530.         DB $02
  4531.         DB $02
  4532.         DB $02
  4533.         DB $02
  4534.         DB $02
  4535.         DB $02
  4536.         DB $02
  4537.         DB $02
  4538.         DB $02
  4539.         DB $02
  4540. ;VIC chip (9000-93FF)
  4541.         DB trap         ;VIC chip
  4542.         DB trap         ;VIA chip
  4543.         DB $02
  4544.         DB $02
  4545. ;alternate colour nybble
  4546.         DB trap
  4547.         DB trap
  4548. ;main colour nybble (in unexpanded VIC) (9600-97FF)
  4549.         DB trap
  4550.         DB trap
  4551. ;more possible expansion RAM (9800-BFFF)
  4552.         DB $02
  4553.         DB $02
  4554.         DB $02
  4555.         DB $02
  4556.         DB $02
  4557.         DB $02
  4558.         DB $02
  4559.         DB $02
  4560.         DB $02
  4561.         DB $02
  4562.         DB $02
  4563.         DB $02
  4564.         DB $02
  4565.         DB $02
  4566.         DB $02
  4567.         DB $02
  4568.         DB $02
  4569.         DB $02
  4570.         DB $02
  4571.         DB $02
  4572.         DB $02
  4573.         DB $02
  4574.         DB $02
  4575.         DB $02
  4576.         DB $02
  4577.         DB $02
  4578.         DB $02
  4579.         DB $02
  4580.         DB $02
  4581.         DB $02
  4582.         DB $02
  4583.         DB $02
  4584.         DB $02
  4585.         DB $02
  4586.         DB $02
  4587.         DB $02
  4588.         DB $02
  4589.         DB $02
  4590.         DB $02
  4591.         DB $02
  4592. ;BASIC2 ROM C000-DFFF
  4593.         DB $02
  4594.         DB $02
  4595.         DB $02
  4596.         DB $02
  4597.         DB $02
  4598.         DB $02
  4599.         DB $02
  4600.         DB $02
  4601.         DB $02
  4602.         DB $02
  4603.         DB $02
  4604.         DB $02
  4605.         DB $02
  4606.         DB $02
  4607.         DB $02
  4608.         DB $02
  4609.         DB $02
  4610.         DB $02
  4611.         DB $02
  4612.         DB $02
  4613.         DB $02
  4614.         DB $02
  4615.         DB $02
  4616.         DB $02
  4617.         DB $02
  4618.         DB $02
  4619.         DB $02
  4620.         DB $02
  4621.         DB $02
  4622.         DB $02
  4623.         DB $02
  4624.         DB $02
  4625. ;KERNAL ROM E000-FFFF
  4626.         DB $02
  4627.         DB $02
  4628.         DB $02
  4629.         DB $02
  4630.         DB $02
  4631.         DB $02
  4632.         DB $02
  4633.         DB $02
  4634.         DB $02
  4635.         DB $02
  4636.         DB $02
  4637.         DB $02
  4638.         DB $02
  4639.         DB $02
  4640.         DB $02
  4641.         DB $02
  4642.         DB $02
  4643.         DB $02
  4644.         DB $02
  4645.         DB $02
  4646.         DB $02
  4647.         DB $02
  4648.         DB $02
  4649.         DB $02
  4650.         DB $02
  4651.         DB $02
  4652.         DB $02
  4653.         DB $02
  4654.         DB $02
  4655.         DB $02
  4656.         DB $02
  4657.         DB $02
  4658. M1pagesize=$-(M1page*256)
  4659.  
  4660.         ORG (IM2page*256)+257
  4661. ;after IM2 IRQ vector table
  4662. ;now use some of this blank space between $B901 and $B9B9
  4663.  
  4664. RAMwrite_trap:
  4665.  
  4666. ;To get to this point the 6502 has tried to write to a page which
  4667. ;is marked "to be trapped". This usually means I/O or screen memory space.
  4668. ;
  4669. ;Some routines just update a RAM copy of a hardware register. Therefore HL is modified from a 6502 address
  4670. ;to a Z80 address and the 6502 instruction works on the "real" Z80 address
  4671. ;
  4672. ;Others require "post-processing" such as writing to the screen. To do this IX is modified to point to another routine.
  4673. ;This routine is called after the 6502 instruction has been run.
  4674. ;An example is the colourRAM routine. Any changes to colour RAM are implemented by changing IX to point to "attr2".
  4675. ;The attr2 routine then updates the Spectrum screen to reflect the change.
  4676.  
  4677.  
  4678. ;on entry
  4679. ;hi-byte of trapped address is in L
  4680. ;lo-byte of trapped address is in C
  4681.  
  4682. ;when finished
  4683. ;hi-byte of new address is taken from A
  4684. ;lo-byte of new address is taken from C
  4685.  
  4686. ;DON'T NEED TO SAVE AF WITH RAMTRAPs AS WE'VE ALREADY PAGED OUT AF
  4687.  
  4688.         LD A,L                  ;get hi-byte of trapped address
  4689.         AND A                   ;set SF flag, is it >=$80xx (ie: VIA or VIC?)
  4690.         JP M,writeIO            ;skip if so
  4691.  
  4692. ;otherwise assume it's the screen
  4693.         LD IX,WriteScreen       ;draw screen once opcode has been done
  4694.         ADD A,ScreenPage-$1E    ;adjust msb so virtual 1E00 goes to real RAM address ($9E00)
  4695.         LD H,A                  ;make HL back to what it was
  4696.         LD L,C
  4697.         LD (RAMtrap),HL         ;make note of addr used
  4698.         RET                     ;back to WRITE memory operation!
  4699.  
  4700.  
  4701.  
  4702. irq_handler:
  4703.  
  4704. ;maskable interrupt (IRQ) has been generated
  4705. ;so push PC and flags on stack
  4706. ;clear BCD mode (like CMOS 6502)
  4707. ;and jump to contents of $FFFE
  4708.  
  4709. ;first un-modify the opcode_decode routine to clear the IRQ
  4710.  
  4711.         LD HL,(M1page*256)+$26  ;LD H,$M1page instead of JR $-4
  4712.                                 ;$26 is opcode for LD H,nn
  4713.         LD (op_decode+1),HL     ;reset 2 bytes to what they normally are
  4714.  
  4715. ;PC (DE) is already correct at this point - so stack it
  4716.         EX AF,AF' ;'
  4717.  
  4718.         LD A,D
  4719.         do_pushA
  4720.         LD A,E
  4721.         do_pushA
  4722.         LD HL,FFrealpage*256+$FE        ;validate it!
  4723.         LD E,(HL)
  4724.         INC L           ;safe to do as we know HL has to be FFFE - therfore validated page still valid
  4725.                         ;also L will never overflow so quicker to do INC L than INC HL
  4726.         LD D,(HL)       ;DE (PC) now contains  vector
  4727.  
  4728.         EX AF,AF' ;'
  4729.         opPHP           ;prepare flags in A
  4730.         AND $EF         ;force B flag to be clear (only IRQ pushes this bit as 0)
  4731.         do_pushA        ;correct flags are in A
  4732.  
  4733.         LD HL,vXflag
  4734.         LD A,(HL)
  4735.         AND $E3         ;clear bits 4,3 and 2 (B,D and I)
  4736.         OR $04          ;have to set bit 2 (I flag)
  4737.         LD (HL),A
  4738. irq_finish:
  4739.         EX AF,AF' ;'
  4740.  
  4741.         JP (IX)         ;no incPC as DE (PC) is already correct
  4742.  
  4743.  
  4744. ;process BREAK as RESTORE key
  4745. kkey10:
  4746.         LD A,$FE
  4747.         IN A,($FE)              ;CAPS pressed?
  4748.         RRCA
  4749. kkey11:
  4750.         RET C           ;exit if not (C) or if is (NC)
  4751.        ld a,0xf7
  4752.        in a,(0xfe)
  4753.        rra ;'1'+cs+space
  4754.        jp nc,quit
  4755.         LD HL,irq1
  4756.         LD A,(HL)
  4757.         XOR $08         ;JR C or JR NC
  4758.         LD (HL),A
  4759.         LD HL,kkey11
  4760.         LD A,(HL)       ;see if we're RET C or RET NC
  4761.         XOR $08         ;D0 or D8
  4762.         LD (HL),A
  4763.         CP $D8          ;=RET C
  4764.         RET Z           ;exit if so because we can now accept a new BREAK press
  4765.  
  4766. kkey12:
  4767.         LD HL,VIA911E   ;IER to see if CA1 is enabled
  4768.         BIT 1,(HL)      ;bit 1 controls CA1
  4769.         RET Z           ;if not set then CA1 has been disabled
  4770.                         ;therefore no restore key
  4771.         DEC HL          ;IFR (911D) shows where irq came from
  4772.         LD A,(HL)
  4773.         OR $82          ;set bits 7 (irq flag) and 1 (CA1 irq)
  4774.         LD (HL),A       ;NMI generate by IM2 routine
  4775.         JP signalNMI    ;CALL/RET
  4776.  
  4777. markIRQ:
  4778.         LD A,(op_decode+1)
  4779.         CP $18
  4780.         JR Z,irq_di             ;IRQ can't override NMI
  4781.         LD A,$18                ;opcode for JR
  4782.         LD (op_decode+1),A      ;force interrupt to be serviced once
  4783.         LD A,irqMD              ;displacement value to get to irqM routine
  4784.         LD (op_decode+2),A
  4785.         JP irq_di
  4786.  
  4787.         ORG (IM2page*256)+257+IM2page
  4788. ;interrupt handler at XYXY address, eg:$B9B9
  4789.  
  4790. ;check for restore (generate NMI regardless of SEI/CLI setting)
  4791.         PUSH AF                 ;preserve flags
  4792.         LD A,$7F
  4793.         IN A,($FE)              ;SPACE pressed?
  4794.         RRCA
  4795. irq1:
  4796.         JR C,irq2
  4797.         PUSH HL
  4798.         CALL kkey10
  4799.         POP HL
  4800. irq2:
  4801.         LD A,(vXflag)
  4802.         AND $04                 ;get I flag
  4803.         JR NZ,irq_di            ;if set then interrupts are disabled
  4804.  
  4805.         LD A,(VIA912E)          ;VIA D2IER
  4806.         AND $40                 ;is TIMER1 enabled?
  4807.         JP NZ,markIRQ           ;if so then get ready to process IRQ
  4808.  
  4809. irq_di:
  4810.  
  4811.         POP AF
  4812.         EI
  4813.         RET
  4814.  
  4815.  
  4816.         ORG Safepage
  4817. ;this table is page aligned for speed
  4818.  
  4819. VIC9000:
  4820.         DB $00
  4821. VIC9001:
  4822.         DB $00
  4823. VIC9002:
  4824.         DB $00
  4825. VIC9003:
  4826.         DB $00
  4827. VIC9004:
  4828.         DB $00
  4829. VIC9005:
  4830.         DB $00
  4831. VIC9006:
  4832.         DB $00
  4833. VIC9007:
  4834.         DB $00
  4835. VIC9008:
  4836.         DB $00
  4837. VIC9009:
  4838.         DB $00
  4839. VIC900A:
  4840.         DB $00
  4841. VIC900B:
  4842.         DB $00
  4843. VIC900C:
  4844.         DB $00
  4845. VIC900D:
  4846.         DB $00
  4847. VIC900E:
  4848.         DB $00
  4849. VIC900F:
  4850.         DB $00
  4851. VIA9110:
  4852.         DB $00
  4853. VIA9111:
  4854.         DB $00
  4855. VIA9112:
  4856.         DB $00
  4857. VIA9113:
  4858.         DB $00
  4859. VIA9114:
  4860.         DB $00
  4861. VIA9115:
  4862.         DB $00
  4863. VIA9116:
  4864.         DB $00
  4865. VIA9117:
  4866.         DB $00
  4867. VIA9118:
  4868.         DB $00
  4869. VIA9119:
  4870.         DB $00
  4871. VIA911A:
  4872.         DB $00
  4873. VIA911B:
  4874.         DB $00
  4875. VIA911C:
  4876.         DB $00
  4877. VIA911D:
  4878.         DB $00
  4879. VIA911E:
  4880.         DB $00
  4881. VIA911F:
  4882.         DB $00
  4883. VIA9120:
  4884.         DB $00
  4885. VIA9121:
  4886.         DB $00
  4887. VIA9122:
  4888.         DB $00
  4889. VIA9123:
  4890.         DB $00
  4891. VIA9124:
  4892.         DB $00
  4893. VIA9125:
  4894.         DB $00
  4895. VIA9126:
  4896.         DB $00
  4897. VIA9127:
  4898.         DB $00
  4899. VIA9128:
  4900.         DB $00
  4901. VIA9129:
  4902.         DB $00
  4903. VIA912A:
  4904.         DB $00
  4905. VIA912B:
  4906.         DB $00
  4907. VIA912C:
  4908.         DB $00
  4909. VIA912D:
  4910.         DB $00
  4911. VIA912E:
  4912.         DB $00
  4913. VIA912F:
  4914.         DB $00
  4915.  
  4916. ;safe gap to stop code being overwritten (AND $3F used so possible to overwrite $30-$3F)
  4917.         DB $00,$00,$00,$00
  4918.         DB $00,$00,$00,$00
  4919.         DB $00,$00,$00,$00
  4920.         DB $00,$00,$00,$00
  4921.  
  4922. IOread:
  4923. ;table used for when READING from VIC and VIA registers
  4924.  
  4925.         DW VICthru      ;$9000 - VIC
  4926.         DW VICthru
  4927.         DW VICthru
  4928.         DW VICraster03  ;bit 7 contains lsb bit of raster
  4929.         DW VICraster04  ;contains bits 1-8 of raster
  4930.         DW VICthru
  4931.         DW VICthru
  4932.         DW VICthru
  4933.         DW VICthru      ;08
  4934.         DW VICthru
  4935.         DW VICthru
  4936.         DW VICthru
  4937.         DW VICthru
  4938.         DW VICthru
  4939.         DW VICthru
  4940.         DW VICthru      ;0F
  4941. ;VIA1
  4942.         DW VIAthru      ;$9110 +00      D1ORB
  4943.         DW D1ORA        ;+01
  4944.         DW VIAthru
  4945.         DW VIAthru
  4946.         DW D1T1lsb      ;TIMER1 counter lsb
  4947.         DW VIAthru
  4948.         DW VIAthru
  4949.         DW VIAthru
  4950.         DW VIAthru
  4951.         DW VIAthru
  4952.         DW VIAthru
  4953.         DW VIAthru
  4954.         DW VIAthru
  4955.         DW VIAthru
  4956.         DW VIAthru
  4957.         DW D1ORA        ;0F (non latching)
  4958. ;VIA2
  4959.         DW D2ORB        ;10 - $9120
  4960.         DW D2ORA        ;11
  4961.         DW VIAthru
  4962.         DW VIAthru
  4963.         DW D2T1lsb      ;TIMER1 counter lsb
  4964.         DW VIAthru
  4965.         DW VIAthru
  4966.         DW VIAthru
  4967.         DW VIAthru
  4968.         DW VIAthru
  4969.         DW VIAthru
  4970.         DW VIAthru
  4971.         DW VIAthru
  4972.         DW VIAthru
  4973.         DW VIAthru
  4974.         DW D2ORA        ;1F (non latching)
  4975.  
  4976. VICthru:
  4977. ;VIC and VIA just read from RAM copy of register
  4978. ;they are the same for now
  4979.        
  4980. VIAthru:
  4981. ;as MSB of VIAthru is safe as MSB of Safepage
  4982. ;H is already correct
  4983. ;and as C is already correct, just ...
  4984.         RET
  4985.  
  4986. D2ORA:
  4987. ;attempt to read from keyboard
  4988.         XOR A
  4989.         IN A,($FE)              ;scan all keys at once
  4990.         CPL
  4991.         AND $1F                 ;convert FF (no keys) to 00 - setting Z flag
  4992.         JR Z,keyQ2              ;if Z then no key pressed so quickly exit
  4993.  
  4994. ;clear previous key states
  4995.         PUSH DE
  4996.         LD HL,vkeypage          ;vkeypage always starts on a page boundary
  4997.         LD B,$08
  4998. key0:   LD (HL),$FF
  4999.         INC L
  5000.         DJNZ key0
  5001.  
  5002. ;read in ZX keyboard (with sym-shift processing)
  5003. readZXkeys:
  5004.         CALL keyrows
  5005.  
  5006. ;now read in which VIC key columns should be read (D2ORB) and only process them
  5007.         LD A,(VIA9120)          ;D2ORB
  5008.         LD D,A
  5009.         LD A,$FF
  5010.         LD HL,vkeypage
  5011.         LD B,$08
  5012. keyskip1:
  5013.         RRC D
  5014.         JR C,keyskip2           ;only merge in if column was required
  5015.         AND (HL)
  5016. keyskip2:
  5017.         INC L                   ;vkeypage is page aligned
  5018.         DJNZ keyskip1
  5019.         POP DE
  5020.  
  5021. keyQ:
  5022.         LD HL,VIA9121           ;D2ORA
  5023.         LD (HL),A
  5024.         LD C,L          ;H already correct from VIA9121
  5025.         RET             ;back to READ memory operation!
  5026. keyQ2:
  5027.         LD HL,VIA9121           ;D2ORA
  5028.         LD (HL),$FF             ;no keys
  5029.         LD C,L          ;H already correct from VIA9121
  5030.         RET             ;back to READ memory operation!
  5031.  
  5032. keyrows:
  5033.         LD BC,$7FFE     ;port
  5034.         IN A,(C)
  5035.         LD B,C          ;set port to $FEFE ready for main loop
  5036.         LD HL,keydata
  5037.         RRCA
  5038.         RRCA            ;is SYM pressed?
  5039.         JP C,key1       ;skip if not
  5040.         LD HL,keydata+$0050     ;80 bytes = 2x40 keys
  5041. key1:
  5042.         IN A,(C)
  5043.         PUSH BC
  5044.         LD B,$05
  5045. key2:
  5046.         RRCA
  5047.         JP NC,keypressed
  5048.         INC HL
  5049. key3:
  5050.         INC HL
  5051.         DJNZ key2
  5052.         POP BC
  5053.         RLC B
  5054.         JP C,key1
  5055.        
  5056.         IN A,(C)        ;BC=$FEFE at this point
  5057.         RRCA            ;is CAPS pressed?
  5058.         RET C           ;finished if not
  5059.  
  5060.         LD A,$EF        ;check for CAPS+number
  5061.         IN A,($FE)
  5062.         OR $E0          ;mask out top 3 bits
  5063.         CP $FF
  5064.         JR NZ,key4      ;deal with 6-0
  5065.         LD A,$7F
  5066.         IN A,($FE)      ;check space ,ie: BREAK
  5067.         RRCA
  5068.         JP C,keyshiftonly
  5069.  
  5070.         LD HL,vkeypage+4
  5071.         SET 0,(HL)      ;mark SPACE as not pressed
  5072.         DEC L           ;onto vkeypage+3
  5073.         RES 0,(HL)      ;mark RUN/STOP as pressed
  5074.         RET
  5075. keyshiftonly:
  5076.         LD HL,vkeypage+3
  5077.         RES 1,(HL)      ;mark LEFT SHIFT as pressed
  5078.         RET
  5079. key4:
  5080.         RRCA            ;deal with CAPS+0
  5081.         JR C,keyshiftonly
  5082.         LD HL,vkeypage          ;deal with col 0
  5083.         RES 7,(HL)              ;mark DELETE as pressed
  5084.         LD HL,vkeypage+7        ;0 is in col 7
  5085.         SET 4,(HL)              ;mark 0 as not pressed
  5086.         RET
  5087.  
  5088.  
  5089. keypressed:
  5090.         LD E,(HL)
  5091.         INC HL
  5092.         LD D,(vkeypage/256)
  5093.         LD C,A          ;preserve A
  5094.         LD A,(DE)       ;get existing key state for VIC20 column
  5095.         AND (HL)        ;change key status as per table
  5096.         LD (DE),A
  5097.         LD A,C          ;restore A
  5098.         JP key3         ;quicker than CALL/RET
  5099.        
  5100. keydata:
  5101.         DB $09,$FF      ;we don't do caps here
  5102.         DB 4,$FD
  5103.         DB 3,$FB
  5104.         db 4,$FB        ;c
  5105.         db 3,$F7        ;v
  5106.         db 2,$FD        ;a
  5107.         db 5,$FD
  5108.         db 2,$FB
  5109.         db 5,$FB
  5110.         db 2,$F7        ;g
  5111.         db 6,$FE        ;q
  5112.         db 1,$FD
  5113.         db 6,$FD
  5114.         db 1,$FB
  5115.         db 6,$FB
  5116.         db 0,$FE ;1
  5117.         db 7,$FE
  5118.         db 0,$FD
  5119.         db 7,$FD
  5120.         db 0,$FB        ;5
  5121.         db 7,$EF        ;0
  5122.         db 0,$EF
  5123.         db 7,$F7
  5124.         db 0,$F7
  5125.         db 7,$FB        ;6
  5126.         db 1,$DF        ;p
  5127.         db 6,$EF
  5128.         db 1,$EF
  5129.         db 6,$F7
  5130.         db 1,$F7        ;y
  5131.         db 1,$7F ;enter
  5132.         db 2,$DF
  5133.         db 5,$EF
  5134.         db 2,$EF
  5135.         db 5,$F7        ;h
  5136.         db 4,$FE        ;space
  5137.         db $09,$ff      ;we don't do sym here
  5138.         db 4,$EF
  5139.         db 3,$EF
  5140.         db 4,$F7        ;b
  5141. ;now with SYM
  5142.         db 9,$ff
  5143.         db 5,$DF        ;':'
  5144.         db 0,$BF        ;'г'
  5145.         db 5,$FE        ;'CBM'
  5146.         db 3,$BF        ;'/'
  5147.         db 3,$FE        ;'run/STOP'     row 2
  5148.         db 9,$ff
  5149.         db 9,$ff
  5150.         db 9,$ff
  5151.         db 9,$ff
  5152.         db 9,$ff        ;row 3
  5153.         db 9,$ff
  5154.         db 9,$ff
  5155.         db 1,$FE        ;'left arrow'
  5156.         db 9,$ff
  5157.         db 4,$7F        ;F1 row 4
  5158.         db 6,$DF        ;"@"
  5159.         db 5,$7F        ;F3
  5160.         db 7,$BF        ;HOME key
  5161.         db 6,$7F        ;F5
  5162.         db 9,$ff        ;row 5
  5163.         db 9,$ff
  5164.         db 2,$7F        ;RIGHT cursor key
  5165.         db 7,$7F        ;F7
  5166.         db 3,$7F        ;DOWN cursor key
  5167.         db 9,$ff        ;row 6
  5168.         db 2,$BF        ;';'
  5169.         db 9,$ff
  5170.         db 9,$ff
  5171.         db 9,$ff
  5172.         db 9,$ff        ;row 7
  5173.         db 5,$BF        ;"="
  5174.         db 0,$DF        ;'+'
  5175.         db 7,$DF        ;'-'
  5176.         db 6,$BF        ;'^'
  5177.         db 9,$ff        ;row 8
  5178.         db 9,$ff
  5179.         db 4,$DF        ;'.'
  5180.         db 3,$DF        ;','
  5181.         db 1,$BF        ;'*'
  5182.  
  5183.  
  5184. RAMread_trap:
  5185. ;on entry
  5186. ;hi-byte of trapped address is in L
  5187. ;lo-byte of trapped address is in C
  5188.  
  5189. ;when finished
  5190. ;hi-byte of new address is taken from H
  5191. ;lo-byte of new address is taken from C
  5192.  
  5193. ;ONLY I/O DEVICES ARE TRAPPED WHEN READING
  5194.  
  5195.         LD A,C
  5196.         AND $3F
  5197.         ADD A,A         ;double up as 2 bytes per entry
  5198.                         ;A would be transferred to BC
  5199.         ADD A,IOread%256        ;effectively do HL+BC
  5200.         LD L,A          ;lsb first
  5201.         LD H,IOread/256 ;msb next - as A must be <$3F and IOread must be $40 bytes into a page
  5202.                         ;(safepage starts on a page boundary), (A*2)+$40 can never overflow from lsb into msb
  5203.         LD B,(HL)
  5204.         INC L           ;quicker to use INC L than INC HL - always in same page
  5205.         LD H,(HL)
  5206.         LD L,B          ;routine address in HL
  5207.  
  5208.         JP (HL)         ;jump to routine
  5209.  
  5210.  
  5211. D1ORA:
  5212. ;read joystick
  5213.         IN A,($1F)      ;read kempston joystick (ZX)
  5214.         RRA             ;ignore bit 0 (RIGHT)
  5215.         AND $0F         ;only want FUDL bits
  5216.         LD HL,Kempston_Table
  5217.         ADD A,L
  5218.         LD L,A          ;let's hope HL+15 doesn't wrap around a page!!
  5219.         LD C,(HL)
  5220.         LD HL,VIA9113   ;DDR on VIA 1, port A
  5221.         LD A,(HL)       ;get which bits are input (=0) and output (=1)
  5222.         CPL             ;we're interested in input bits, so flip
  5223.         AND C           ;and only keep joystick bits if they're input enabled
  5224.         LD C,A
  5225.         LD L,VIA9111%256        ;H already correct
  5226.         LD A,(HL)       ;joystick is bits 5,4,3,2
  5227.         AND $C3         ;so only keep bits 7,6,1,0 of existing VIA value
  5228.         OR C            ;merge in joystick
  5229.         LD (HL),A       ;store it in RAM copy of register
  5230.         LD C,L          ;H already setup
  5231.         RET
  5232.  
  5233. D2ORB:
  5234. ;read right bit of joystick
  5235.         LD HL,VIA9122           ;VIA2 DDRB
  5236.         LD C,VIA9120%256        ;H is already correct
  5237.         BIT 7,(HL)
  5238.         RET NZ          ;DDR says this port is for output if bit 7 set
  5239.                         ;so no joystick check - therefore skip
  5240.         IN A,($1F)      ;kempston joystick
  5241.         CPL             ;flip bits
  5242.         AND $01
  5243.         RRCA            ;joystick R bit into bit 7
  5244.         LD B,A
  5245.         LD A,(HL)
  5246.         AND $7F
  5247.         OR B            ;merge in joystick
  5248.         LD (HL),A       ;store in VIA9120 (VIA 2 IO PORT B)
  5249.         RET             ;H & C already set correctly
  5250.  
  5251. D2T1lsb:
  5252.         LD HL,VIA9124   ;lsb of T1
  5253.         JR randomT1
  5254.  
  5255. D1T1lsb:
  5256.         LD HL,VIA9114   ;lsb of T1
  5257. randomT1:
  5258.         LD A,R
  5259.         RLA             ;R doesn't set bit 7 randomly, so let's assume CF is random here!
  5260.         LD (HL),A
  5261.         LD C,L          ;H already correct
  5262.         RET
  5263.  
  5264.  
  5265. vtemp2:
  5266.         DB $00
  5267.  
  5268. complain:
  5269.         LD A,$06
  5270.         OUT ($FE),A
  5271.         JR complain
  5272.  
  5273.  
  5274.  
  5275. writeIO:
  5276.  
  5277. ;RAM Write trap continues here
  5278. ;at this point A=msb of trapped address (copy of L register)
  5279. ;and C=lsb of trapped address
  5280.  
  5281. ;when finished
  5282. ;hi-byte of new address is taken from H
  5283. ;lo-byte of new address is taken from C
  5284.  
  5285. ;only traps >= $8000 come here - everything else goes to screen write!
  5286.  
  5287.         CP $94
  5288.         JR C,writeIO2   ;we've not trapped a colour RAM write so skip attr1 routine
  5289.  
  5290. attr1:
  5291. ;in this case HL should be between $9400-$97FF (colour RAM)
  5292.         LD IX,attr2
  5293.         AND $01                 ;A is 0 or 1 depending on it being $94/96 or $95/97
  5294.         ADD A,colourram         ;adjust HL so it points to host's
  5295.         LD H,A                  ;address of colour RAM
  5296.         LD L,C
  5297.         LD (RAMtrap),HL         ;6502 will be working on real copy of colour RAM
  5298.         RET
  5299.  
  5300. writeIO2:
  5301.         CP $90
  5302.         JR Z,VICchipOUT         ;if not $90 then we must be writing to $91xx (VIA)
  5303.  
  5304. VIAout:
  5305.         LD A,C                  ;get lo-byte of original address back
  5306.         AND $3F
  5307.         LD C,A                  ;store safe (0-3F) version of lsb back in C
  5308.         LD H,Safepage/256       ;write into RAM copy of h/w register
  5309.                                 ;H and C now correct
  5310.         CPL                     ;flip bits in A
  5311.         AND $0F                 ;is it 911F or 912F?
  5312.         CP $0F
  5313.         RET C                   ;exit if not
  5314.  
  5315. ;       CP $0E
  5316. ;       RET C                   ;finished unless we're talking +0E or +0F
  5317.        
  5318. ;       CP $0F
  5319. ;       JR NZ,VIAout2
  5320.         LD A,C                  ;deal with 911F and 912F
  5321.         AND $F1                 ;force $1F to 11 and $2F to 21
  5322.         LD C,A                  ;update C
  5323.         RET                     ;done!
  5324.        
  5325. VIAout2:
  5326. ;deal with IER of each VIA
  5327.         LD A,C
  5328.         AND $20                 ;are we dealing with VIA2
  5329. ;       JR Z,VIAout3            ;jump if so
  5330.  
  5331. ;       LD IX,DealWithIER1
  5332.         RET                     ;done! (H & C already correct)
  5333.  
  5334. VIAout3:
  5335. ;       LD IX,DealWithIER2
  5336.         RET                     ;done! (H & C already correct)
  5337.  
  5338. DealWithIER2:
  5339.         LD HL,VIA912E
  5340.         JP dealwithIER
  5341.  
  5342. DealWithIER1:
  5343.         LD HL,VIA911E
  5344.  
  5345. dealwithIER:
  5346.         EX AF,AF' ;'
  5347.         LD IX,op_decode
  5348.         LD A,(BC)
  5349.         BIT 7,A
  5350.         JR Z,clearIER
  5351. ;set IER:
  5352.  
  5353.         OR (HL)                 ;merge in existing IER
  5354.         LD (HL),A
  5355.         EX AF,AF' ;'            ;back to 6502 AF
  5356.         JP (IX)
  5357. clearIER:
  5358.  
  5359.         CPL
  5360.         AND (HL)                ;reset bits which were set to 1
  5361.         OR $80                  ;bit 7 is always set when reading back in
  5362.         LD (HL),A
  5363.         EX AF,AF' ;'            ;back to 6502 AF
  5364.         JP (IX)
  5365.  
  5366.  
  5367. VICchipOUT:
  5368.         LD A,C
  5369.         AND $0F                 ;keep to 00-0F
  5370.         LD C,A                  ;update C (lsb)
  5371.         ADD A,A                 ;double up VIC register (00-0F becomes 00-1E)
  5372.         LD HL,VICtable          ;VICtable doesn't cross page boundary at any point
  5373.         ADD A,L                 ;add lsb of VICtable to A
  5374.         LD L,A                  ;which is lsb for HL
  5375.         LD A,(HL)               ;can't corrupt C so use A instead
  5376.         INC HL
  5377.         LD B,(HL)
  5378.  
  5379.         DB $DD
  5380.         LD H,B                  ;copy B/A into IX
  5381.         DB $DD                  ;as IX routine will deal with the write request
  5382.         LD L,A 
  5383.  
  5384.         LD H,Safepage/256       ;write into RAM copy of h/w register
  5385.                                 ;C (lsb) is already correct
  5386.         RET
  5387.  
  5388. rVIC900F:
  5389.         EX AF,AF' ;'            ;save 6502 AF
  5390.         LD A,(VIC900F)
  5391.         LD H,A
  5392.         AND $08
  5393.         OR $30
  5394.         LD (attr4b),a           ;$30=jr nc, $38=jr c
  5395.                                 ;default is to JR C,attr6 (effectively jr to attr5)
  5396. VIC900Fb:
  5397.         LD A,H
  5398.         AND $F0                 ;only need top 4 bits of $900F for background colour
  5399.         LD L,A
  5400.  
  5401.         LD H,attrs/256
  5402.         LD A,(HL)               ;convert VIC value (bbbb0fff) into ZX ATTR value
  5403.         LD HL,VICbackg
  5404.         CP (HL)                 ;has colour changed?
  5405.         LD (HL),A               ;set background colour
  5406.         CALL NZ,refreshattr     ;refresh whole screen if colour has changed
  5407.                                 ;and carry on into border routine either way
  5408.  
  5409. VIC900Fd:
  5410. ;sort out border
  5411.         LD IX,op_decode
  5412.         LD A,(VIC900F)          ;get original $900F register contents back
  5413.         AND $07                 ;keep lower bits 0-2 which has border in it
  5414.  
  5415.         LD L,A
  5416.         ADD A,A
  5417.         ADD A,A
  5418.         ADD A,A
  5419.         ADD A,A                 ;multiply by 16 to make paper colour (upper) = border (lower ink)
  5420.         OR L                    ;add original ink back in (ink=paper here)
  5421.         LD L,A
  5422.         LD H,attrs/256
  5423.         LD A,(HL)               ;convert VIC colour to Speccy colour
  5424.         AND $3F                 ;filter out BRIGHT/FLASH attributes as border can't be bright
  5425.         LD (VIC9002d+1),A
  5426.         AND $07
  5427.         OUT ($FE),A
  5428.  
  5429.         LD A,(WriteScreenSize+1)
  5430.         NEG                     ;convert back to 0-31
  5431.         LD L,A
  5432.         JP VIC9002b1            ;don't need to alter screensize so skip first bit
  5433.                                 ;this routine draws the "inner border".
  5434.  
  5435. rVIC9002:
  5436. ;number of columns
  5437. ;also manipulates colourRAM location
  5438.  
  5439.         EX AF,AF' ;'            ;save 6502 AF
  5440.         LD IX,op_decode
  5441.         LD BC,$0102
  5442.         LD A,(VIC9002)
  5443.         AND $80
  5444.         RLCA
  5445.         RLCA                    ;A now =0 or =2
  5446.         ADD A,$94               ;colourRAM base msb now in A                           
  5447.         LD L,A
  5448.         LD H,MWpage
  5449.         LD (HL),B               ;=trap!
  5450.         INC L
  5451.         LD (HL),B               ;=trap!
  5452. ;       XOR $02                 ;trap might not always be =2, but this needs to be =2 for it to work
  5453.         XOR C                   ;change A to the opposite base
  5454.         LD L,A
  5455.         LD (HL),C               ;=dump to ROM (unused)
  5456.         INC L
  5457.         LD (HL),C               ;=dump to ROM (unused)
  5458.  
  5459.         LD A,(VIC9002)
  5460.         AND $1F                 ;ignore bit 7 and keep column width as 1-31
  5461.  
  5462. VIC9002b:
  5463.         LD L,A          ;width of screen in L
  5464.         NEG             ;before we negate it
  5465.         LD (WriteScreenSize+1),A
  5466.                         ;adjust VIC column size as required
  5467. VIC9002b1:
  5468.         LD H,$58
  5469.         LD BC,$0020
  5470.  
  5471. VIC9002c:
  5472.         BIT 5,L         ;have we done all 31 cols yet? (we have if we're now at 32)
  5473.         JR NZ,VIC9002e  ;skip if so
  5474.  
  5475. ;draw vertical lines
  5476. VIC9002d:
  5477.         LD (HL),$00     ;this value is changed as required
  5478.         ADD HL,BC
  5479.         LD A,H
  5480.         CP $5B          ;have we gone outside attr area?
  5481.         JR NZ,VIC9002d  ;keep going until we do
  5482.         LD H,$58        ;top of attr again
  5483.         INC L           ;next column
  5484.         JP VIC9002c     ;loop until done!
  5485.  
  5486. ;draw horizontal rows
  5487. VIC9002e:
  5488.         LD A,$18        ;24 ZX rows
  5489.         LD HL,write0-1
  5490.         SUB (HL)        ;subtract number of VIC rows from 24
  5491.         JR Z,VIC9002h   ;no border rows to draw (row depth =24) so skip
  5492.         LD B,A          ;we've got B number of rows to do false border in
  5493.         LD HL,$5B00
  5494.         LD A,(VIC9002d+1)       ;VIC border colour
  5495.  
  5496. VIC9002f:
  5497.         PUSH BC
  5498.         LD B,$20        ;32 cols
  5499. VIC9002g:
  5500.         DEC HL
  5501.         LD (HL),A
  5502.         DJNZ VIC9002g
  5503.         POP BC
  5504.         DJNZ VIC9002f
  5505. VIC9002h:
  5506.         JP rVIC9005b    ;process start of screen memory (also affected by bit 7 of $9002)
  5507.  
  5508. rVIC9003:
  5509. ;number of rows
  5510.         EX AF,AF' ;'    ;save 6502 AF
  5511.         LD A,(VIC9003)
  5512.         AND $7F         ;drop bit 7
  5513.         RRA             ;div by 2 (CF will be cleared by above AND)
  5514.                         ;CF now shows whether we're in 8 or 16 high characters
  5515.         LD HL,writescreen4
  5516.         JR NC,rVIC9003_8
  5517. rVIC9003_16:
  5518.         LD (HL),$29     ;opcode for ADD HL,HL - needed for 16 high characters
  5519.         LD HL,attr316
  5520.         LD (HL),$87     ;ADD A,A
  5521.         LD HL,display7bytes16
  5522.         JR VIC9003a
  5523. rVIC9003_8:
  5524.         LD (HL),$00
  5525.         LD HL,attr316
  5526.         LD (HL),$00     ;NOP
  5527.         LD HL,display7bytes8
  5528. VIC9003a:
  5529.         PUSH DE
  5530.         LD DE,write3
  5531.         LDI
  5532.         LDI             ;do this for 7 bytes
  5533.         LDI    
  5534.         LDI
  5535.         LDI
  5536.         LDI
  5537.         LDI
  5538.         LDI             ;NEEDS TO BE FOR 8 BYTES NOW DUE TO EXTRA AF,AF'
  5539.         POP DE
  5540.         DEC A           ;setting rows to zero upsets screendraw routine!
  5541.                         ;0-24 to 255-23
  5542.         CP $18          ;only up to 24 rows allowed
  5543.         JR C,VIC9003b
  5544.         LD A,$17        ;force to 23+1 rows
  5545. VIC9003b:
  5546.         INC A           ;bring back to 1-24
  5547.         LD (write0-1),A ;alter gfx routine to display correct number of rows
  5548.         LD (write1+1),A
  5549.         LD (attr3-1),A  ;and attribute routine too
  5550.         LD (attr4a+1),A
  5551.         CALL refreshattr
  5552.         LD IX,op_decode
  5553.         JP VIC9002e     ;exit via column routine to draw new false border
  5554.                         ;only need to draw rows because columns can't have changed via $9003
  5555.  
  5556.  
  5557. rVIC9005:
  5558.         EX AF,AF' ;'    ;save 6502 AF
  5559.  
  5560. ;deal with charset pointer first
  5561.  
  5562.         LD A,(VIC9005)
  5563.         LD B,$0F
  5564.         AND B                   ;0-15 only
  5565.         LD HL,CharsetTranslation-$0F00  ;compensate for BC being $0Fxx
  5566.         LD C,A
  5567.         ADD HL,BC
  5568.         LD A,(HL)       ;get new value for charset
  5569.         LD HL,WriteScreenSize-$02
  5570.         INC (HL)                ;force an update
  5571.         LD (WriteScreenCharset+2),A     ;adjust character set pointer as required
  5572.  
  5573.  
  5574. rVIC9005b:
  5575.  
  5576. ;now deal with screen memory
  5577. ;  X = ($9005) AND 112
  5578. ;  Y = ($9002) AND 128
  5579. ;  Address = 4*Y + 64*X
  5580. ;
  5581. ;    X       Y         Address
  5582. ;
  5583. ;    128       0             0          0
  5584. ;    128     128          $200        512
  5585. ;    144       0          $400       1024
  5586. ;    144     128          $600       1536
  5587. ;    160       0          $800       2048
  5588. ;    160     128          $A00       2560
  5589. ;    176       0          $C00       3072
  5590. ;    176     128          $E00       3584
  5591. ;    192       0         $1000       4096
  5592. ;    192     128         $1200       4608
  5593. ;    208       0         $1400       5120
  5594. ;    208     128         $1600       5632
  5595. ;    224       0         $1800       6144
  5596. ;    224     128         $1A00       6656
  5597. ;    240       0         $1C00       7168
  5598. ;    240     128         $1E00       7680
  5599.  
  5600.         LD HL,(oldVDUtrap)      ;address in MW table that was altered
  5601.         LD BC,(oldVDUrambytes)  ;previous contents of those addresses
  5602.         LD (HL),C
  5603.         INC L
  5604.         LD (HL),B               ;effectively untrap them
  5605.         LD A,(VIC9002)
  5606.         RLCA                    ;move bit 7 into C flag
  5607.         LD A,(VIC9005)
  5608.         RRA             ;take bit 7 of $9002 into account
  5609.         RRCA            ;shift significant nybble into
  5610.         RRCA
  5611.         RRCA            ;least significant nybble
  5612.         AND $1F         ;keep screen memory bits only (32 different values)
  5613.         LD C,A
  5614.         LD HL,screenmemorymap
  5615.         LD B,$00
  5616.         ADD HL,BC
  5617.         LD A,(HL)                       ;page to be trapped (also page+1)
  5618.         LD HL,WriteScreenSize-$02
  5619.         CP (HL)                         ;have we changed? (this code is also called from elsewhere)
  5620.         LD (HL),A
  5621.         CALL NZ,RedrawScreen            ;if we have then redraw entire screen
  5622.         SUB ZPrealpage                  ;adjust to 6502 memory space (ie:$90 = ZX real address, convert to $10 = VIC real address)
  5623.         LD L,A
  5624.         LD H,MWpage
  5625.         LD (oldVDUtrap),HL
  5626.         LD C,(HL)
  5627.         LD (HL),trap            ;mark as trap
  5628.         INC L
  5629.         LD B,(HL)
  5630.         LD (HL),trap            ;mark as trap
  5631.         LD (oldVDUrambytes),BC
  5632.         EX AF,AF' ;'            ;restore 6502 AF
  5633.         LD IX,op_decode
  5634.         JP (IX)
  5635.  
  5636. VICraster04:
  5637.         LD HL,VIC9004   ;point to bits 1-8 of raster
  5638.         LD C,L
  5639.         JP VICraster03b ;use same routine as raster03 in case software only reads $9004
  5640.                         ;we've still got to increase $9004 and keep it in range
  5641.  
  5642. VICraster03:
  5643.         LD HL,VIC9003
  5644.         LD A,(HL)
  5645.         ADD A,$80
  5646.         LD (HL),A
  5647.         LD C,L          ;H already correct
  5648.         RET NC          ;finished if bit 0 of raster went from 0 to 1
  5649.         INC L           ;HL to point to VIC9004 (rest of raster)
  5650.  
  5651. VICraster03b:
  5652.         INC (HL)        ;increase VIC9004 (rest of raster)
  5653.         RET P           ;finished if 0-127 (which is 0-255 for raster)
  5654.         LD A,(HL)
  5655.         CP $9C          ;max value for raster is 311, so we need to check against 312/2
  5656.         RET C           ;finished if we're under
  5657.         LD (HL),$00     ;back to 0
  5658.         RET
  5659.  
  5660.  
  5661. rVICsoundvol:
  5662. ;sound volume
  5663.         EX AF,AF' ;'    ;save 6502 AF
  5664. rVICsoundvol1:
  5665.         LD IX,op_decode
  5666.         LD BC,$FFFD     ;port $FFFD - sound port on 128
  5667.         LD H,$08        ;R8 - vol A
  5668.         OUT (C),H
  5669.         LD B,$BF        ;want port $BFFD now
  5670.         LD A,(VIC900E)
  5671.         AND $0F         ;keep to 0-15
  5672.         OUT (C),A       ;set volume
  5673.  
  5674.         INC H
  5675.         LD B,$FF        ;port $FFFD again
  5676.         OUT (C),H
  5677.         LD B,$BF        ;want port $BFFD now
  5678.         OUT (C),A       ;set volume on channel B
  5679.  
  5680.         INC H
  5681.         LD B,$FF        ;port $FFFD again
  5682.         OUT (C),H
  5683.         LD B,$BF        ;want port $BFFD now
  5684.         OUT (C),A       ;set volume on channel C
  5685.  
  5686. ;now turn channels on/off
  5687.  
  5688.         LD BC,$8000
  5689.         LD HL,VIC900D
  5690.         LD A,(HL)
  5691.         AND B                   ;is sound channel enabled?
  5692.         JR Z,rVICsoundvol2      ;0=off
  5693.         INC C                   ;set bit 0. This will be shifted into bit 3.
  5694.                                 ;noise is on channel A.
  5695.  
  5696. rVICsoundvol2:
  5697.         SLA C
  5698.         DEC HL          ;VIC900C
  5699.  
  5700.         LD A,(HL)
  5701.         AND B                   ;is sound channel enabled?
  5702.         JR Z,rVICsoundvol3      ;0=off
  5703.         INC C
  5704.  
  5705. rVICsoundvol3:
  5706.         SLA C
  5707.         DEC HL          ;VIC900B
  5708.  
  5709.         LD A,(HL)
  5710.         AND B                   ;is sound channel enabled?
  5711.         JR Z,rVICsoundvol4      ;0=off
  5712.         INC C
  5713.  
  5714. rVICsoundvol4:
  5715.         SLA C
  5716.         DEC HL          ;VIC900A
  5717.  
  5718.         LD A,(HL)
  5719.         AND B                   ;is sound channel enabled?
  5720.         JR Z,rVICsoundvol5      ;0=off
  5721.         INC C
  5722.  
  5723. rVICsoundvol5:
  5724.         LD A,C          ;channels on/off in H now
  5725.         CPL             ;flip because 0=on on the AY chip!
  5726.         LD H,A
  5727.         LD BC,$FFFD     ;sound port on 128
  5728.         LD A,$07        ;R7 - tone/noise selection
  5729.         OUT (C),A
  5730.         LD B,$BF        ;want port $BFFD now
  5731.         OUT (C),H       ;enable all 3 tone channels and possibly noise channel on A
  5732.  
  5733.         EX AF,AF' ;'    ;restore 6502 AF
  5734.         JP (IX)
  5735.  
  5736. rVICsoundA:
  5737. ;IX set via rVICsoundvol
  5738.         EX AF,AF' ;'    ;save 6502 AF
  5739.         LD A,(VIC900A)
  5740.         CPL             ;255 is highest note
  5741.         LD L,A
  5742.         LD H,$00
  5743.         LD B,H
  5744.         LD C,L          ;copy HL into BC
  5745.         ADD HL,HL       ;x2
  5746.         ADD HL,BC       ;x3
  5747.         ADD HL,HL       ;x6
  5748.         ADD HL,HL       ;x12
  5749.         ADD HL,BC       ;x13
  5750.         ADD HL,HL       ;x26
  5751.                         ;real value should be 25.6, but this is close enough!
  5752.         LD BC,$FFFD
  5753.         XOR A           ;R0 - lsb of tone for channel A
  5754.         OUT (C),A       ;select register of 128 sound chip
  5755.         LD B,$BF        ;port $BFFD
  5756.         OUT (C),L       ;out lsb of period
  5757.         LD B,$FF
  5758.         INC A           ;R1 - msb of tone
  5759.         OUT (C),A
  5760.         LD B,$BF
  5761.         OUT (C),H       ;out msb of period
  5762.         JP rVICsoundvol1        ;if not then channel should be silent!
  5763.                                 ;so just set volume to 0 via this routine
  5764.  
  5765.  
  5766. rVICsoundB:
  5767. ;IX set via rVICsoundvol
  5768.         EX AF,AF' ;'    ;save 6502 AF
  5769.         LD A,(VIC900B)
  5770.         CPL
  5771.         LD L,A
  5772.         LD H,$00
  5773.         LD B,H
  5774.         LD C,L          ;copy HL into BC
  5775.         ADD HL,HL       ;x2
  5776.         ADD HL,BC       ;x3
  5777.         ADD HL,HL       ;x6
  5778.         ADD HL,HL       ;x12
  5779.         ADD HL,BC       ;x13
  5780.                         ;real value should be 12.8, but this is close enough!
  5781.         LD BC,$FFFD
  5782.         LD A,$02        ;R2 - lsb of tone for channel B
  5783.         OUT (C),A       ;select register of 128 sound chip
  5784.         LD B,$BF        ;port $BFFD
  5785.         OUT (C),L       ;out lsb of period
  5786.         LD B,$FF
  5787.         INC A           ;R3 - msb of tone
  5788.         OUT (C),A
  5789.         LD B,$BF
  5790.         OUT (C),H       ;out msb of period
  5791.         JP rVICsoundvol1        ;if not then channel should be silent!
  5792.                                 ;so just set volume to 0 via this routine
  5793.  
  5794. rVICsoundC:
  5795. ;IX set via rVICsoundvol
  5796.         EX AF,AF' ;'    ;save 6502 AF
  5797.         LD A,(VIC900C)
  5798.         CPL
  5799.         LD L,A
  5800.         LD H,$00
  5801.         LD B,H
  5802.         SRL A           ;halve A
  5803.         LD C,A          ;so half HL is in BC
  5804.         ADD HL,BC       ;x1.5
  5805.         ADD HL,HL       ;x3
  5806.         ADD HL,HL       ;x6
  5807.         ADD HL,BC       ;x6.5
  5808.                         ;real value should be 6.4, but this is close enough!
  5809.         LD BC,$FFFD
  5810.         LD A,$04        ;R4 - lsb of tone for channel C
  5811.         OUT (C),A       ;select register of 128 sound chip
  5812.         LD B,$BF        ;port $BFFD
  5813.         OUT (C),L       ;out lsb of period
  5814.         LD B,$FF
  5815.         INC A           ;R5 - msb of tone
  5816.         OUT (C),A
  5817.         LD B,$BF
  5818.         OUT (C),H       ;out msb of period
  5819.         JP rVICsoundvol1        ;if not then channel should be silent!
  5820.                                 ;so just set volume to 0 via this routine
  5821.  
  5822. rVICsoundD:
  5823. ;IX set via rVICsoundvol
  5824.         EX AF,AF' ;'    ;save 6502 AF
  5825.         LD A,(VIC900D)
  5826.         CPL             ;255 is highest note
  5827.         LD L,A
  5828.         LD H,$00
  5829.         LD B,H
  5830.         LD C,L          ;copy HL into BC
  5831.  
  5832.         ADD HL,HL       ;x2
  5833.         ADD HL,BC       ;x3
  5834.         ADD HL,HL       ;x6
  5835.         ADD HL,HL       ;x12
  5836.         ADD HL,BC       ;x13
  5837.  
  5838. ;       LD A,L          ;keep only lsb of result as noise channel only has 5-bit resolution on AY
  5839.         SRL L           ;halve A
  5840.         SRL L           ;quarter A as quarter of 13 = 3.25
  5841.                         ;real value should be 3.2, but this is close enough!
  5842.  
  5843.         LD BC,$FFFD
  5844.         LD A,$06        ;R6 - tone for noise channel
  5845.         OUT (C),A       ;select register of 128 sound chip
  5846.         LD B,$BF        ;port $BFFD
  5847.         OUT (C),L       ;out lsb of period
  5848.         JP rVICsoundvol1
  5849.  
  5850. refreshattr:
  5851.         LD HL,colourram*256     ;start at top left
  5852.         LD IX,refreshattr2
  5853.         PUSH AF                 ;save our AF because both AF and AF' will be destroyed
  5854. refreshattr1:
  5855.         PUSH HL                 ;remember which attr square we're updating for later
  5856.         PUSH DE                 ;preserve DE
  5857.  
  5858.         JP attr30B              ;refresh attr
  5859. ;JP (IX) comes back here with 6502 AF paged in and POP DE already done
  5860. refreshattr2:
  5861.         POP HL                  ;get which attr square we're updating back
  5862.         INC HL
  5863.         LD A,colourram+2        ;done all 512? (2 pages = 512 bytes)
  5864.         CP H
  5865.         JP NZ,refreshattr1
  5866.         POP AF                  ;restore 6502 AF as current AF
  5867.         RET
  5868.  
  5869. RedrawScreen:
  5870.         PUSH AF
  5871.         LD H,A                  ; H will contain 'screenpage'
  5872.         LD L,$00
  5873.         LD IX,redraw2
  5874.         LD BC,$0200
  5875. redraw1:
  5876.         PUSH BC
  5877.         PUSH HL
  5878.         JP WriteDirect
  5879. redraw2:
  5880.         POP HL
  5881.         INC HL
  5882.         POP BC
  5883.         DEC BC
  5884.         LD A,B
  5885.         OR C
  5886.         JR NZ,redraw1
  5887.         POP AF
  5888.         RET
  5889.  
  5890. ;FOLLOWING IS BASED ON GEOFF WEARMOUTH'S ROM DISASSEMBLY
  5891. ;It is not verified to work yet (on real hardware)
  5892. ;It allos you to load a headerless block of code into VIC RAM space from 0000 upwards
  5893.  
  5894. ; ------------------------------------
  5895. ; Load header or block of information
  5896. ; ------------------------------------
  5897. ;   This routine is used to load bytes and on entry A is set to $00 for a
  5898. ;   header or to $FF for data.  IX points to the start of receiving location
  5899. ;   and DE holds the length of bytes to be loaded. If, on entry the carry flag
  5900. ;   is set then data is loaded, if reset then it is verified.
  5901.  
  5902. ;; LD-BYTES
  5903. L0556:  INC     D               ; reset the zero flag without disturbing carry.
  5904.         EX      AF,AF' ;'          ; preserve entry flags.
  5905.         DEC     D               ; restore high byte of length.
  5906.  
  5907.         DI                      ; disable interrupts
  5908.  
  5909.         LD      A,$0F           ; make the border white and mic off.
  5910.         OUT     ($FE),A         ; output to port.
  5911.  
  5912.  
  5913. ;   the reading of the EAR bit (D6) will always be preceded by a test of the
  5914. ;   space key (D0), so store the initial post-test state.
  5915.  
  5916.         IN      A,($FE)         ; read the ear state - bit 6.
  5917.         RRA                     ; rotate to bit 5.
  5918.         AND     $20             ; isolate this bit.
  5919.         OR      $02             ; combine with red border colour.
  5920.         LD      C,A             ; and store initial state long-term in C.
  5921.         CP      A               ; set the zero flag.
  5922.  
  5923. ;
  5924.  
  5925. ;; LD-BREAK
  5926. L056B:  RET     NZ              ; return if at any time space is pressed.
  5927.  
  5928. ;; LD-START
  5929. L056C:  CALL    L05E7           ; routine LD-EDGE-1
  5930.         JR      NC,L056B        ; back to LD-BREAK with time out and no
  5931.                                 ; edge present on tape.
  5932.  
  5933. ;   but continue when a transition is found on tape.
  5934.  
  5935.         LD      HL,$0415        ; set up 16-bit outer loop counter for
  5936.                                 ; approx 1 second delay.
  5937.  
  5938. ;; LD-WAIT
  5939. L0574:  DJNZ    L0574           ; self loop to LD-WAIT (for 256 times)
  5940.  
  5941.         DEC     HL              ; decrease outer loop counter.
  5942.         LD      A,H             ; test for
  5943.         OR      L               ; zero.
  5944.         JR      NZ,L0574        ; back to LD-WAIT, if not zero, with zero in B.
  5945.  
  5946. ;   continue after delay with H holding zero and B also.
  5947. ;   sample 256 edges to check that we are in the middle of a lead-in section.
  5948.  
  5949.         CALL    L05E3           ; routine LD-EDGE-2
  5950.         JR      NC,L056B        ; back to LD-BREAK
  5951.                                 ; if no edges at all.
  5952.  
  5953. ;; LD-LEADER
  5954. L0580:  LD      B,$9C           ; set timing value.
  5955.         CALL    L05E3           ; routine LD-EDGE-2
  5956.         JR      NC,L056B        ; back to LD-BREAK if time-out
  5957.  
  5958.         LD      A,$C6           ; two edges must be spaced apart.
  5959.         CP      B               ; compare
  5960.         JR      NC,L056C        ; back to LD-START if too close together for a
  5961.                                 ; lead-in.
  5962.  
  5963.         INC     H               ; proceed to test 256 edged sample.
  5964.         JR      NZ,L0580        ; back to LD-LEADER while more to do.
  5965.  
  5966. ;   sample indicates we are in the middle of a two or five second lead-in.
  5967. ;   Now test every edge looking for the terminal sync signal.
  5968.  
  5969. ;; LD-SYNC
  5970. L058F:  LD      B,$C9           ; initial timing value in B.
  5971.         CALL    L05E7           ; routine LD-EDGE-1
  5972.         JR      NC,L056B        ; back to LD-BREAK with time-out.
  5973.  
  5974.         LD      A,B             ; fetch augmented timing value from B.
  5975.         CP      $D4             ; compare
  5976.         JR      NC,L058F        ; back to LD-SYNC if gap too big, that is,
  5977.                                 ; a normal lead-in edge gap.
  5978.  
  5979. ;   but a short gap will be the sync pulse.
  5980. ;   in which case another edge should appear before B rises to $FF
  5981.  
  5982.         CALL    L05E7           ; routine LD-EDGE-1
  5983.         RET     NC              ; return with time-out.
  5984.  
  5985. ; proceed when the sync at the end of the lead-in is found.
  5986. ; We are about to load data so change the border colours.
  5987.  
  5988.         LD      A,C             ; fetch long-term mask from C
  5989.         XOR     $03             ; and make blue/yellow.
  5990.  
  5991.         LD      C,A             ; store the new long-term byte.
  5992.  
  5993.         LD      H,$00           ; set up parity byte as zero.
  5994.         LD      B,$B0           ; timing.
  5995.         JR      L05C8           ; forward to LD-MARKER
  5996.                                 ; the loop mid entry point with the alternate
  5997.                                 ; zero flag reset to indicate first byte
  5998.                                 ; is discarded.
  5999.  
  6000. ; --------------
  6001. ;   the loading loop loads each byte and is entered at the mid point.
  6002.  
  6003. ;; LD-LOOP
  6004. L05A9:  EX      AF,AF' ;'          ; restore entry flags and type in A.
  6005.         JR      NZ,L05B3        ; forward to LD-FLAG if awaiting initial flag
  6006.                                 ; which is to be discarded.
  6007.  
  6008.         JR      NC,L05BD        ; forward to LD-VERIFY if not to be loaded.
  6009.  
  6010.         EX AF,AF' ;'
  6011.         LD B,MRpage             ;this allows us to write ROM cart area
  6012.         DB $DD
  6013.         LD C,H
  6014.         LD A,(BC)               ;translated page
  6015.         DEC A                   ;now has correct value
  6016.         LD B,A
  6017.         DB $DD
  6018.         LD C,L                  ;ZX address in BC
  6019.         EX AF,AF' ;'
  6020.         LD A,L                  ;byte loaded from tape (must keep!)
  6021.         LD (BC),A               ; place loaded byte at memory location.
  6022.         JR L05C2           ; forward to LD-NEXT
  6023.  
  6024. ; ---
  6025.  
  6026. ;; LD-FLAG
  6027. ;first byte is 00 for header, FF for data
  6028. ;last byte is parity
  6029. L05B3:  RL      C               ; preserve carry (verify) flag in long-term
  6030.                                 ; state byte. Bit 7 can be lost.
  6031.  
  6032.         XOR     L               ; compare type in A with first byte in L.
  6033.         RET     NZ              ; return if no match e.g. CODE vs. DATA.
  6034.  
  6035. ;   continue when data type matches.
  6036.  
  6037.         LD      A,C             ; fetch byte with stored carry
  6038.         RRA                     ; rotate it to carry flag again
  6039.         LD      C,A             ; restore long-term port state.
  6040.  
  6041.         JR      L05C5           ; forward to LD-DEC.
  6042.                                 ; but why not to location after ?
  6043.  
  6044.  
  6045. ;;LD-VERIFY
  6046. L05BD:
  6047.  
  6048. ;; LD-NEXT
  6049. L05C2:  INC     IX              ; increment byte pointer.
  6050.  
  6051. ;; LD-DEC
  6052. L05C4:  DEC     DE              ; decrement length.
  6053.  
  6054. L05C5:
  6055.         EX      AF,AF' ;'          ; store the flags.
  6056.         LD      B,$B2           ; timing.
  6057.  
  6058. ;   when starting to read 8 bits the receiving byte is marked with bit at right.
  6059. ;   when this is rotated out again then 8 bits have been read.
  6060.  
  6061. ;; LD-MARKER
  6062. L05C8:  LD      L,$01           ; initialize as %00000001
  6063.  
  6064. ;; LD-8-BITS
  6065. ;returns byte loaded in L
  6066. L05CA:  CALL    L05E3           ; routine LD-EDGE-2 increments B relative to
  6067.                                 ; gap between 2 edges.
  6068.         RET     NC              ; return with time-out.
  6069.  
  6070.         LD      A,$CB           ; the comparison byte.
  6071.         CP      B               ; compare to incremented value of B.
  6072.                                 ; if B is higher then bit on tape was set.
  6073.                                 ; if <= then bit on tape is reset.
  6074.  
  6075.         RL      L               ; rotate the carry bit into L.
  6076.  
  6077.         LD      B,$B0           ; reset the B timer byte.
  6078.         JP      NC,L05CA        ; JUMP back to LD-8-BITS
  6079.  
  6080. ;   when carry set then marker bit has been passed out and byte is complete.
  6081.  
  6082.         LD      A,H             ; fetch the running parity byte.
  6083.         XOR     L               ; include the new byte.
  6084.         LD      H,A             ; and store back in parity register.
  6085.  
  6086.         LD      A,D             ; check length of
  6087.         OR      E               ; expected bytes.
  6088.         JR      NZ,L05A9        ; back to LD-LOOP
  6089.                                 ; while there are more.
  6090.  
  6091. ;   when all bytes loaded then parity byte should be zero.
  6092.  
  6093.         LD      A,H             ; fetch parity byte.
  6094.         CP      $01             ; set carry if zero.
  6095.         RET                     ; return
  6096.                                 ; in no carry then error as checksum disagrees.
  6097. ; -------------------------
  6098. ; Check signal being loaded
  6099. ; -------------------------
  6100. ;   An edge is a transition from one mic state to another.
  6101. ;   More specifically a change in bit 6 of value input from port $FE.
  6102. ;   Graphically it is a change of border colour, say, blue to yellow.
  6103. ;   The first entry point looks for two adjacent edges. The second entry point
  6104. ;   is used to find a single edge.
  6105. ;   The B register holds a count, up to 256, within which the edge (or edges)
  6106. ;   must be found. The gap between two edges will be more for a '1' than a '0'
  6107. ;   so the value of B denotes the state of the bit (two edges) read from tape.
  6108.  
  6109. ; ->
  6110.  
  6111. ;; LD-EDGE-2
  6112. L05E3:  CALL    L05E7           ; call routine LD-EDGE-1 below.
  6113.         RET     NC              ; return if space pressed or time-out.
  6114.                                 ; else continue and look for another adjacent
  6115.                                 ; edge which together represent a bit on the
  6116.                                 ; tape.
  6117.  
  6118. ; ->
  6119. ;   this entry point is used to find a single edge from above but also
  6120. ;   when detecting a read-in signal on the tape.
  6121.  
  6122. ;; LD-EDGE-1
  6123. L05E7:  LD      A,$16           ; a delay value of twenty two.
  6124.  
  6125. ;; LD-DELAY
  6126. L05E9:  DEC     A               ; decrement counter
  6127.         JR      NZ,L05E9        ; loop back to LD-DELAY 22 times.
  6128.  
  6129.         AND      A              ; clear carry.
  6130.  
  6131. ;; LD-SAMPLE
  6132. L05ED:  INC     B               ; increment the time-out counter.
  6133.         RET     Z               ; return with failure when $FF passed.
  6134.  
  6135.         LD      A,$7F           ; prepare to read keyboard and EAR port
  6136.         IN      A,($FE)         ; row $7FFE. bit 6 is EAR, bit 0 is SPACE key.
  6137.         RRA                     ; test outer key the space. (bit 6 moves to 5)
  6138.         RET     NC              ; return if space pressed.  >>>
  6139.  
  6140.         XOR     C               ; compare with initial long-term state.
  6141.         AND     $20             ; isolate bit 5
  6142.         JR      Z,L05ED         ; back to LD-SAMPLE if no edge.
  6143.  
  6144. ;   but an edge, a transition of the EAR bit, has been found so switch the
  6145. ;   long-term comparison byte containing both border colour and EAR bit.
  6146.  
  6147.         LD      A,C             ; fetch comparison value.
  6148.         CPL                     ; switch the bits
  6149.         LD      C,A             ; and put back in C for long-term.
  6150.  
  6151.         AND     $07             ; isolate new colour bits.
  6152.         OR      $08             ; set bit 3 - MIC off.
  6153.         OUT     ($FE),A         ; send to port to effect the change of colour.
  6154.  
  6155.         SCF                     ; set carry flag signaling edge found within
  6156.                                 ; time allowed.
  6157.         RET                     ; return.
  6158.  
  6159.  
  6160. VICLOAD:
  6161.         PUSH IX
  6162.         PUSH DE
  6163.         PUSH AF
  6164.         LD IX,$0000
  6165.         LD DE,$4000
  6166.         LD A,$FF
  6167.         SCF
  6168.         CALL L0556
  6169.         POP AF
  6170.         POP DE
  6171.         POP IX
  6172.         EI
  6173.         LD DE,$E5B5     ;VIC KERNAL panic
  6174.         JP (IX)         ;back to 6502
  6175.  
  6176.         ORG $1450+base
  6177. VICtable:
  6178. ;MUST NOT STRADDLE A PAGE BOUNDARY!
  6179. ;list of routines that deal with each register of VIC chip
  6180. ;when WRITING to register
  6181.         DW VICignore
  6182.         DW VICignore
  6183.         DW rVIC9002     ;col width
  6184.         DW rVIC9003     ;row depth
  6185.         DW VICignore
  6186.         DW rVIC9005     ;charmap pointer
  6187.         DW VICignore
  6188.         DW VICignore
  6189.         DW VICignore
  6190.         DW VICignore
  6191.         DW rVICsoundA   ;channel A
  6192.         DW rVICsoundB   ;channel B
  6193.         DW rVICsoundC   ;channel C
  6194.         DW VICignore
  6195.         DW rVICsoundvol ;sound volume
  6196.         DW rVIC900F     ;border colour
  6197.  
  6198. VICignore:
  6199.         LD IX,op_decode
  6200.         EX AF,AF' ;'            ;restore 6502 AF
  6201.         JP (IX)         ;ignore value and carry on!
  6202.  
  6203. ;was org $0e00+base
  6204.  
  6205.         ORG $1490+base
  6206. CharsetTranslation:
  6207. ;safe place for CHARSET translation table
  6208. ;subtract 240 from POKE $9005,x value
  6209.         DB chargen/256
  6210.         DB (chargen/256)+4
  6211.         DB (chargen/256)+8
  6212.         DB (chargen/256)+12
  6213.         DB $00          ;would be VIC i/o space
  6214.         DB colourram    ;colour RAM
  6215.         DB $00
  6216.         DB $00          ;these 2 would do nothing anyway
  6217.         DB ZPrealpage   ;page 0!
  6218.         DB ZPrealpage+4 ;1024
  6219.         DB ZPrealpage+8 ;2048
  6220.         DB ZPrealpage+12        ;3192
  6221.         DB ZPrealpage+16
  6222.         DB ZPrealpage+20
  6223.         DB ZPrealpage+24
  6224.         DB ZPrealpage+28        ;7168
  6225. screenmemorymap:
  6226. ;take bits 7-4 of $9005. Rotate right
  6227. ;move bit 7 of $9002 into bit 7 of result
  6228.         DB 0                    ;$8000
  6229.         DB 0
  6230.         DB 0
  6231.         DB 0
  6232.         DB 0
  6233.         DB 0
  6234.         DB 0
  6235.         DB 0
  6236.         DB ZPrealpage
  6237.         DB ZPrealpage+4
  6238.         DB ZPrealpage+8
  6239.         DB ZPrealpage+12
  6240.         DB ZPrealpage+16
  6241.         DB ZPrealpage+20
  6242.         DB ZPrealpage+24
  6243.         DB ZPrealpage+28
  6244.         DB 0                    ;$8200
  6245.         DB 0
  6246.         DB 0
  6247.         DB 0
  6248.         DB 0
  6249.         DB 0
  6250.         DB 0
  6251.         DB 0
  6252.         DB ZPrealpage+2
  6253.         DB ZPrealpage+6
  6254.         DB ZPrealpage+10
  6255.         DB ZPrealpage+14
  6256.         DB ZPrealpage+18
  6257.         DB ZPrealpage+22
  6258.         DB ZPrealpage+26
  6259.         DB ZPrealpage+30
  6260. oldVDUtrap:
  6261.         DW vkeypage             ;address in MW table that was altered
  6262.                                 ;fill with dummy address to stop it altering $0000/$01
  6263. oldVDUrambytes:
  6264.         DW $00                  ;previous contents of those addresses
  6265.  
  6266.  
  6267.         ORG base+$1000
  6268.  
  6269. ;this is a safe blank area to use that's on a page boundary
  6270. vkeypage:
  6271.         DB $00
  6272.         DB $00
  6273.         DB $00
  6274.         DB $00
  6275.         DB $00
  6276.         DB $00
  6277.         DB $00
  6278.         DB $00
  6279.  
  6280.  
  6281.         ORG base+$08C6
  6282. ;kempston table - converts IN31 to VIC equivalent
  6283. ;this 16-byte table must not cross a page boundary!
  6284. ;it doesn't have to be page aligned though!
  6285.  
  6286. ;don't need bit 0 of IN 31 (RIGHT) as that's in a separate VIC register
  6287.  
  6288. Kempston_Table:
  6289.         DB $FF  ;nothing pressed (all values INVERTED)
  6290.         DB $EF  ;L (bit 4 on VIC)
  6291.         DB $F7  ;D (bit 3 on VIC)
  6292.         DB $E7  ;LD
  6293.         DB $FB  ;U (bit 2 on VIC)
  6294.         DB $EB  ;LU
  6295.         DB $F3  ;UD
  6296.         DB $E3  ;LUD
  6297.         DB $DF  ;F      (bit 5 on VIC)
  6298.         DB $CF  ;FL
  6299.         DB $D7  ;FD
  6300.         DB $C7  ;FLD
  6301.         DB $D3  ;FU
  6302.         DB $CB  ;FLU
  6303.         DB $D3  ;FUD
  6304.         DB $C3  ;FLUD
  6305.  
  6306.         ORG base+$2600
  6307. ;this occupies last page before MR,MW,M1,IRQroutine,IM2 tables
  6308. rowtable:
  6309.         DW $4000
  6310.         DW $4020
  6311.         DW $4040
  6312.         DW $4060
  6313.         DW $4080
  6314.         DW $40A0
  6315.         DW $40C0
  6316.         DW $40E0
  6317.         DW $4800
  6318.         DW $4820
  6319.         DW $4840
  6320.         DW $4860
  6321.         DW $4880
  6322.         DW $48A0
  6323.         DW $48C0
  6324.         DW $48E0
  6325.         DW $5000
  6326.         DW $5020
  6327.         DW $5040
  6328.         DW $5060
  6329.         DW $5080
  6330.         DW $50A0
  6331.         DW $50C0
  6332.         DW $50E0
  6333. ;repeat list of addresses again in case somebody sets row depth >24
  6334.         DW $4000
  6335.         DW $4020
  6336.         DW $4040
  6337.         DW $4060
  6338.         DW $4080
  6339.         DW $40A0
  6340.         DW $40C0
  6341.         DW $40E0
  6342.         DW $4800
  6343.         DW $4820
  6344.         DW $4840
  6345.         DW $4860
  6346.         DW $4880
  6347.         DW $48A0
  6348.         DW $48C0
  6349.         DW $48E0
  6350.  
  6351.  
  6352. VICborder:
  6353.         DB $00
  6354. VICbackg:
  6355.         DB $00
  6356. VICforeg:
  6357.         DB $00
  6358.  
  6359.  
  6360.         ORG base+$2500
  6361. attrs:
  6362. ;       R   G   B
  6363. ;                       needs to go Ggg Rrr Bb
  6364. ;black  00  00  00
  6365. ;       000 000 00 = $00        = 000 000 00 = $00
  6366. ;white  FF  FF  FF
  6367. ;       111 111 11 = $FF        = 111 111 11 = $FF
  6368. ;red    B4  18  18
  6369. ;       110 001 00 = $C4        = 001 110 00 = $38
  6370. ;cyan   4C  E6  D8
  6371. ;       010 110 10 = $5A        = 110 010 10 = $CA
  6372. ;purple BC  29  CA
  6373. ;       110 001 10 = $C6        = 001 110 10 = $3A
  6374. ;green  42  E4  36
  6375. ;       010 110 01 = $59        = 110 010 01 = $C9
  6376. ;blue   32  2A  C8
  6377. ;       001 001 10 = $2C        = 001 001 10 = $26
  6378. ;yellow D2  E1  26
  6379. ;       110 110 01 = $D9        = 110 110 01 = $D9
  6380. ;orange CA  5A  02
  6381. ;       110 011 00 = $CC        = 011 110 00 = $78
  6382. ;l oran DE  AC  80
  6383. ;       110 101 10 = $D6        = 101 110 10 = $BA
  6384. ;pink   DC  94  94
  6385. ;       110 100 10 = $D2        = 100 110 10 = $9A
  6386. ;l cyan A5  F4  EC
  6387. ;       101 111 11 = $BF        = 111 101 11 = $F7
  6388. ;l purp E0  9A  E4
  6389. ;       110 101 11 = $D7        = 101 110 11 = $BB
  6390. ;l grn  A0  F2  9A
  6391. ;       101 111 10 = $BE        = 111 101 10 = $F6
  6392. ;l blue 9C  92  E4
  6393. ;       101 100 11 = $B3        = 100 101 11 = $97
  6394. ;l yel  EF  F8  9A
  6395. ;       111 111 10 = $FE        = 111 111 10 = $FE
  6396.  
  6397.  
  6398.  
  6399. ;8 cols is black,white,red,cyan,purple,green,blue,yellow
  6400.  
  6401.         ORG attrs
  6402.         DB 0    ; p=blk i=blk
  6403.         DB 7    ; p=blk i=wht
  6404.         DB 2    ; p=blk i=red
  6405.         DB 5    ; p=blk i=cyn
  6406.         DB 3    ; p=blk i=pur
  6407.         DB 4    ; p=blk i=grn
  6408.         DB 1    ; p=blk i=blu
  6409.         DB 6    ; p=blk i=yel
  6410.         DB 6    ; p=blk i=ora
  6411.         DB 70   ; p=blk i=l ora
  6412.         DB 66   ; p=blk i=l pnk
  6413.         DB 69   ; p=blk i=l cyn
  6414.         DB 67   ; p=blk i=l pur
  6415.         DB 68   ; p=blk i=l grn
  6416.         DB 65   ; p=blk i=l blu
  6417.         DB 70   ; p=blk i=l yel
  6418.         DB 56   ; p=wht i=blk
  6419.         DB 63   ; p=wht i=wht
  6420.         DB 58   ; p=wht i=red
  6421.         DB 61   ; p=wht i=cyn
  6422.         DB 59   ; p=wht i=pur
  6423.         DB 60   ; p=wht i=grn
  6424.         DB 57   ; p=wht i=blu
  6425.         DB 62   ; p=wht i=yel
  6426.         DB 62   ; p=wht i=ora
  6427.         DB 126  ; p=wht i=l ora
  6428.         DB 122  ; p=wht i=l pnk
  6429.         DB 125  ; p=wht i=l cyn
  6430.         DB 123  ; p=wht i=l pur
  6431.         DB 124  ; p=wht i=l grn
  6432.         DB 121  ; p=wht i=l blu
  6433.         DB 126  ; p=wht i=l yel
  6434.         DB 16   ; p=red i=blk
  6435.         DB 23   ; p=red i=wht
  6436.         DB 18   ; p=red i=red
  6437.         DB 21   ; p=red i=cyn
  6438.         DB 19   ; p=red i=pur
  6439.         DB 20   ; p=red i=grn
  6440.         DB 17   ; p=red i=blu
  6441.         DB 22   ; p=red i=yel
  6442.         DB 22   ; p=red i=ora
  6443.         DB 86   ; p=red i=l ora
  6444.         DB 83   ; p=red i=l pnk clash
  6445.         DB 85   ; p=red i=l cyn
  6446.         DB 83   ; p=red i=l pur
  6447.         DB 84   ; p=red i=l grn
  6448.         DB 81   ; p=red i=l blu
  6449.         DB 86   ; p=red i=l yel
  6450.         DB 40   ; p=cyn i=blk
  6451.         DB 47   ; p=cyn i=wht
  6452.         DB 42   ; p=cyn i=red
  6453.         DB 45   ; p=cyn i=cyn
  6454.         DB 43   ; p=cyn i=pur
  6455.         DB 44   ; p=cyn i=grn
  6456.         DB 41   ; p=cyn i=blu
  6457.         DB 46   ; p=cyn i=yel
  6458.         DB 46   ; p=cyn i=ora
  6459.         DB 110  ; p=cyn i=l ora
  6460.         DB 106  ; p=cyn i=l pnk
  6461.         DB 77   ; p=cyn i=l cyn
  6462.         DB 107  ; p=cyn i=l pur
  6463.         DB 108  ; p=cyn i=l grn
  6464.         DB 105  ; p=cyn i=l blu
  6465.         DB 110  ; p=cyn i=l yel
  6466.         DB 24   ; p=pur i=blk
  6467.         DB 31   ; p=pur i=wht
  6468.         DB 26   ; p=pur i=red
  6469.         DB 29   ; p=pur i=cyn
  6470.         DB 27   ; p=pur i=pur
  6471.         DB 28   ; p=pur i=grn
  6472.         DB 25   ; p=pur i=blu
  6473.         DB 30   ; p=pur i=yel
  6474.         DB 30   ; p=pur i=ora
  6475.         DB 94   ; p=pur i=l ora
  6476.         DB 90   ; p=pur i=l pnk
  6477.         DB 93   ; p=pur i=l cyn
  6478.         DB 93   ; p=pur i=l pur clash
  6479.         DB 92   ; p=pur i=l grn
  6480.         DB 89   ; p=pur i=l blu
  6481.         DB 94   ; p=pur i=l yel
  6482.         DB 32   ; p=grn i=blk
  6483.         DB 39   ; p=grn i=wht
  6484.         DB 34   ; p=grn i=red
  6485.         DB 37   ; p=grn i=cyn
  6486.         DB 35   ; p=grn i=pur
  6487.         DB 36   ; p=grn i=grn
  6488.         DB 33   ; p=grn i=blu
  6489.         DB 38   ; p=grn i=yel
  6490.         DB 38   ; p=grn i=ora
  6491.         DB 102  ; p=grn i=l ora
  6492.         DB 98   ; p=grn i=l pnk
  6493.         DB 101  ; p=grn i=l cyn
  6494.         DB 99   ; p=grn i=l pur
  6495.         DB 101  ; p=grn i=l grn clash
  6496.         DB 97   ; p=grn i=l blu
  6497.         DB 102  ; p=grn i=l yel
  6498.         DB 8    ; p=blu i=blk
  6499.         DB 15   ; p=blu i=wht
  6500.         DB 10   ; p=blu i=red
  6501.         DB 13   ; p=blu i=cyn
  6502.         DB 11   ; p=blu i=pur
  6503.         DB 12   ; p=blu i=grn
  6504.         DB 9    ; p=blu i=blu
  6505.         DB 14   ; p=blu i=yel
  6506.         DB 14   ; p=blu i=ora
  6507.         DB 78   ; p=blu i=l ora
  6508.         DB 74   ; p=blu i=l pnk
  6509.         DB 77   ; p=blu i=l cyn
  6510.         DB 75   ; p=blu i=l pur
  6511.         DB 76   ; p=blu i=l grn
  6512.         DB 77   ; p=blu i=l blu clash
  6513.         DB 78   ; p=blu i=l yel
  6514.         DB 48   ; p=yel i=blk
  6515.         DB 55   ; p=yel i=wht
  6516.         DB 50   ; p=yel i=red
  6517.         DB 53   ; p=yel i=cyn
  6518.         DB 51   ; p=yel i=pur
  6519.         DB 52   ; p=yel i=grn
  6520.         DB 49   ; p=yel i=blu
  6521.         DB 54   ; p=yel i=yel
  6522.         DB 50   ; p=yel i=ora clash
  6523.         DB 114  ; p=yel i=l ora clash
  6524.         DB 114  ; p=yel i=l pnk
  6525.         DB 117  ; p=yel i=l cyn
  6526.         DB 115  ; p=yel i=l pur
  6527.         DB 116  ; p=yel i=l grn
  6528.         DB 113  ; p=yel i=l blu
  6529.         DB 119  ; p=yel i=l yel clash
  6530.         DB 48   ; p=ora i=blk
  6531.         DB 55   ; p=ora i=wht
  6532.         DB 50   ; p=ora i=red
  6533.         DB 53   ; p=ora i=cyn
  6534.         DB 51   ; p=ora i=pur
  6535.         DB 52   ; p=ora i=grn
  6536.         DB 49   ; p=ora i=blu
  6537.         DB 22   ; p=ora i=yel clash
  6538.         DB 54   ; p=ora i=ora
  6539.         DB 86   ; p=ora i=l ora clash
  6540.         DB 114  ; p=ora i=l pnk
  6541.         DB 117  ; p=ora i=l cyn
  6542.         DB 115  ; p=ora i=l pur
  6543.         DB 116  ; p=ora i=l grn
  6544.         DB 113  ; p=ora i=l blu
  6545.         DB 22   ; p=ora i=l yel clash
  6546.         DB 112  ; p=l ora i=blk
  6547.         DB 119  ; p=l ora i=wht
  6548.         DB 114  ; p=l ora i=red
  6549.         DB 117  ; p=l ora i=cyn
  6550.         DB 115  ; p=l ora i=pur
  6551.         DB 116  ; p=l ora i=grn
  6552.         DB 113  ; p=l ora i=blu
  6553.         DB 86   ; p=l ora i=yel clash
  6554.         DB 86   ; p=l ora i=ora clash
  6555.         DB 118  ; p=l ora i=l ora
  6556.         DB 114  ; p=l ora i=l pnk
  6557.         DB 117  ; p=l ora i=l cyn
  6558.         DB 115  ; p=l ora i=l pur
  6559.         DB 116  ; p=l ora i=l grn
  6560.         DB 113  ; p=l ora i=l blu
  6561.         DB 119  ; p=l ora i=l yel clash
  6562.         DB 80   ; p=l pnk i=blk
  6563.         DB 87   ; p=l pnk i=wht
  6564.         DB 83   ; p=l pnk i=red clash
  6565.         DB 85   ; p=l pnk i=cyn
  6566.         DB 83   ; p=l pnk i=pur
  6567.         DB 84   ; p=l pnk i=grn
  6568.         DB 81   ; p=l pnk i=blu
  6569.         DB 86   ; p=l pnk i=yel
  6570.         DB 86   ; p=l pnk i=ora
  6571.         DB 86   ; p=l pnk i=l ora
  6572.         DB 82   ; p=l pnk i=l pnk
  6573.         DB 85   ; p=l pnk i=l cyn
  6574.         DB 83   ; p=l pnk i=l pur
  6575.         DB 84   ; p=l pnk i=l grn
  6576.         DB 81   ; p=l pnk i=l blu
  6577.         DB 86   ; p=l pnk i=l yel
  6578.         DB 104  ; p=l cyn i=blk
  6579.         DB 111  ; p=l cyn i=wht
  6580.         DB 106  ; p=l cyn i=red
  6581.         DB 105  ; p=l cyn i=cyn clash
  6582.         DB 107  ; p=l cyn i=pur
  6583.         DB 108  ; p=l cyn i=grn
  6584.         DB 105  ; p=l cyn i=blu
  6585.         DB 110  ; p=l cyn i=yel
  6586.         DB 110  ; p=l cyn i=ora
  6587.         DB 110  ; p=l cyn i=l ora
  6588.         DB 106  ; p=l cyn i=l pnk
  6589.         DB 109  ; p=l cyn i=l cyn
  6590.         DB 107  ; p=l cyn i=l pur
  6591.         DB 108  ; p=l cyn i=l grn
  6592.         DB 105  ; p=l cyn i=l blu
  6593.         DB 110  ; p=l cyn i=l yel
  6594.         DB 88   ; p=l pur i=blk
  6595.         DB 95   ; p=l pur i=wht
  6596.         DB 90   ; p=l pur i=red
  6597.         DB 93   ; p=l pur i=cyn
  6598.         DB 93   ; p=l pur i=pur clash
  6599.         DB 92   ; p=l pur i=grn
  6600.         DB 89   ; p=l pur i=blu
  6601.         DB 94   ; p=l pur i=yel
  6602.         DB 94   ; p=l pur i=ora
  6603.         DB 94   ; p=l pur i=l ora
  6604.         DB 90   ; p=l pur i=l pnk
  6605.         DB 93   ; p=l pur i=l cyn
  6606.         DB 91   ; p=l pur i=l pur
  6607.         DB 92   ; p=l pur i=l grn
  6608.         DB 89   ; p=l pur i=l blu
  6609.         DB 94   ; p=l pur i=l yel
  6610.         DB 96   ; p=l grn i=blk
  6611.         DB 103  ; p=l grn i=wht
  6612.         DB 98   ; p=l grn i=red
  6613.         DB 101  ; p=l grn i=cyn
  6614.         DB 99   ; p=l grn i=pur
  6615.         DB 101  ; p=l grn i=grn clash
  6616.         DB 97   ; p=l grn i=blu
  6617.         DB 102  ; p=l grn i=yel
  6618.         DB 102  ; p=l grn i=ora
  6619.         DB 102  ; p=l grn i=l ora
  6620.         DB 98   ; p=l grn i=l pnk
  6621.         DB 101  ; p=l grn i=l cyn
  6622.         DB 99   ; p=l grn i=l pur
  6623.         DB 100  ; p=l grn i=l grn
  6624.         DB 97   ; p=l grn i=l blu
  6625.         DB 102  ; p=l grn i=l yel
  6626.         DB 72   ; p=l blu i=blk
  6627.         DB 79   ; p=l blu i=wht
  6628.         DB 74   ; p=l blu i=red
  6629.         DB 77   ; p=l blu i=cyn
  6630.         DB 75   ; p=l blu i=pur
  6631.         DB 76   ; p=l blu i=grn
  6632.         DB 72   ; p=l blu i=blu clash
  6633.         DB 78   ; p=l blu i=yel
  6634.         DB 78   ; p=l blu i=ora
  6635.         DB 78   ; p=l blu i=l ora
  6636.         DB 74   ; p=l blu i=l pnk
  6637.         DB 77   ; p=l blu i=l cyn
  6638.         DB 75   ; p=l blu i=l pur
  6639.         DB 76   ; p=l blu i=l grn
  6640.         DB 73   ; p=l blu i=l blu
  6641.         DB 78   ; p=l blu i=l yel
  6642.         DB 112  ; p=l yel i=blk
  6643.         DB 119  ; p=l yel i=wht
  6644.         DB 114  ; p=l yel i=red
  6645.         DB 117  ; p=l yel i=cyn
  6646.         DB 115  ; p=l yel i=pur
  6647.         DB 116  ; p=l yel i=grn
  6648.         DB 113  ; p=l yel i=blu
  6649.         DB 119  ; p=l yel i=yel clash
  6650.         DB 114  ; p=l yel i=ora clash
  6651.         DB 114  ; p=l yel i=l ora clash
  6652.         DB 114  ; p=l yel i=l pnk
  6653.         DB 117  ; p=l yel i=l cyn
  6654.         DB 115  ; p=l yel i=l pur
  6655.         DB 116  ; p=l yel i=l grn
  6656.         DB 113  ; p=l yel i=l blu
  6657.         DB 118  ; p=l yel i=l yel
  6658.  
  6659. ;#END
  6660.         ;display "begin=",begin
  6661. end=(M1page*256)+M1pagesize
  6662.         display "end=",end
  6663.  
  6664.  
  6665.         savebin "vic20.com",begin,end-begin
  6666.  
  6667.         LABELSLIST "../../us/user.l"
  6668.