Home » Archimedes archive » Zipped Apps » 6502em » !6502Em/src/6502Elk18
!6502Em/src/6502Elk18
This website contains an archive of files for the Acorn Electron, BBC Micro, Acorn Archimedes, Commodore 16 and Commodore 64 computers, which Dominic Ford has rescued from his private collection of floppy disks and cassettes.
Some of these files were originally commercial releases in the 1980s and 1990s, but they are now widely available online. I assume that copyright over them is no longer being asserted. If you own the copyright and would like files to be removed, please contact me.
Tape/disk: | Home » Archimedes archive » Zipped Apps » 6502em |
Filename: | !6502Em/src/6502Elk18 |
Read OK: | ✔ |
File size: | 8E1D bytes |
Load address: | 0000 |
Exec address: | 0000 |
File contents
10REM > 6502Em 20master=FALSE 30*RMENSURE 6502Support 0.00 RMRun <6502Em$Res>.65Support 40ON ERROR PROCerror 50REM 60 70IO_Podule%=FALSE 80 90DIM opcode(&100), bcd(&100), code 500*1024, buffer 1000 100DIM l%(100) 110DIM divloop1(10),divloop2(10),divjump(10) 120div%=0 130LIBRARY "<6502Em$Dir>.Src.Sound6" 140LIBRARY "<6502Em$Dir>.Src.Opcodes" 150LIBRARY "<6502Em$Dir>.Src.Screen" 160 170electron%=TRUE 180PROCassemble 190 200PRINT(end-start)/1024 210OSCLI "Save <6502Em$Dir>.CodeE "+STR$~code+" "+STR$~(end+code) 220OSCLI "SetType <6502Em$Dir>.CodeE Data" 230 240END 250 260OSCLI"LOAD <6502Em$Dir>.OS1,2 "+STR$~(memory+&C000) 270OSCLI"LOAD <6502Em$Dir>.BASICII "+STR$~(memory+&8000) 280 290MODE 12 300CALL init+code 310PRINT"BOO" 320 330!pc_store=&D9CD << 16 340 350D%=memory : REM R3 360CALL start+code 370 380END 390DEFPROCassemble 400PROCclearmem(code,code+200*1024) 410R=1000 : S=1000 : T=1000 420 430A=4 440X=5 450Y=6 460F=7 470SP=8 480mem=3 490time=9 500zpc=10 510table=11 520 530a=-&100+0 540x=-&100+4 550y=-&100+8 560f=-&100+12 570sp=-&100+16 580pc_store=-&100+20 590T1mode=-&100+24 600T2mode=-&100+25 610T3mode=-&100+26 620T4mode=-&100+27 630T1=-&100+28 640T1R=-&100+32 650T2=-&100+36 660T2R=-&100+40 670T3=-&100+44 680T3R=-&100+48 690T4=-&100+52 700T4R=-&100+56 710screen=-&100+60 720screenR=-&100+64 730min=-&100+68 740sound_timer=-&100+72 750ifr=-&100+76 760ier=-&100+77 770ifr2=-&100+78 780ier2=-&100+79 790arc_screenstart=-&100+80 800tamper=-&100+84 810cursor_tamper=-&100+88 820ROMSEL_ON=-&100+92 830rom=-&100+96 840ROMRAM=-&100+100 850fe20=-&100+116 860tape_handle=-&100+117 870crt_regs=-&100+120 880scratch=-&100+140 890pal_regs=-&100+148 900Palette=-&100+164 910ACCCON=-&100+172 920patch_on=-&100+176 930pal_tamper=-&100+177 940lastmode=-&100+178 950fe10=-&100+179 960tape_count=-&100+180 970key_addr=-&100+184 980Elatch=-&100+188 990Eifr=-&100+189 1000Eier=-&100+190 1010ROMint=-&100+191 1020speedR=-&100+196 1030enD=-&100+192 1040 1050enD=-&100+200 : REM don't go past this 1060 1070FORp=4 TO 6 STEP 2 1080div%=0 1090O%=code 1100l%=0 1110P%=0 1120opcode%=0 1130[OPTp 1140.Oa EQUD 0 1150.Ox EQUD 0 1160.Oy EQUD 0 1170.Of EQUD 0 1180.Osp EQUD 0 1190.Opc_store EQUD 0 1200.start_offset EQUD start 1210.trace EQUD 0 1220.trace2 EQUD 0 1230.init_addr EQUD init 1240.crt_addr EQUD 0 ; was crt_regs 1250.T1_addr EQUD 0 ; was T1 1260.ifr_addr EQUD 0 ; ifr 1270.column_counter_addr EQUD 0 ; column_counter 1280.ROMSEL_addr EQUD 0 ; ROMSEL 1290.Palette_addr EQUD 0 ; Palette 1300.speed_addr EQUD screen_count+4 1310.elite_addr EQUD 0 ; elite 1320.opco_addr EQUD opcode(0) ; opcodetable 1330.bcd_addr EQUD bcd(0) 1340.sheila_writetab_addr EQUD sheila_writetab 1350.sheila_readtab_addr EQUD sheila_readtab 1360.sound_vectors_addr EQUD sound_buffs_addr 1370.patch_addr EQUD patch_screen 1380 1390.init ; only called once, before code called 1400ADR R0,0 1410;LDR R1,opco_addr 1420;ADD R1,R1,R0 1430;LDR R2,bcd_addr 1440;ADD R2,R2,R0 1450LDR R5,sheila_writetab_addr 1460ADD R5,R5,R0 1470LDR R6,sheila_readtab_addr 1480ADD R6,R6,R0 1490MOV R3,#255 1500.init_loop 1510;LDR R4,[R1,R3,LSL#2] 1520;ADD R4,R4,R0 1530;STR R4,[R1,R3,LSL#2] 1540;LDR R4,[R2,R3,LSL#2] 1550;ADD R4,R4,R0 1560;STR R4,[R2,R3,LSL#2] 1570LDR R4,[R5,R3,LSL#2] 1580ADD R4,R4,R0 1590STR R4,[R5,R3,LSL#2] 1600LDR R4,[R6,R3,LSL#2] 1610ADD R4,R4,R0 1620STR R4,[R6,R3,LSL#2] 1630SUBS R3,R3,#1 1640BPL init_loop 1650MOV PC,R14 1660 1670.start 1680STMFD R13!,{R1-R12,R14} 1690STR R13,return_addr 1700STR R0,roms_addr 1710;LDR R0,crt_addr 1720;ADR R1,0 1730;ADD R0,R0,R1 1740;SWI "6502_Init" 1750 1760;MOV R0,#&4000 1770 1780 1790 1800;STR R0,[mem,#screenR] 1810;MOV R0,#&9C00 : ;ADD R0,R0,#&40 1820;STR R0,[mem,#T1R] 1830; 1840MOV R0,R0,LSR#2 1850STR R0,[mem,#T1] 1860MOV R0,R0,LSR#2 1870STR R0,[mem,#screen] 1880 1890;SWI "6502_Getkeyaddr" 1900SWI "6502_GetElectronKeys" 1910STR R0,[mem,#key_addr] 1920 1930ADR R0,block1 1940ADD R1,R0,#8 1950SWI "OS_ReadVduVariables" 1960LDR R9,[R1] ; screenstart 1970STR R9,[mem,#arc_screenstart] 1980MOV R9,#1 1990STRB R9,[mem,#tamper] 2000STRB R9,[mem,#pal_tamper] 2010STRB R9,[mem,#cursor_tamper] 2020 2030LDR A,[mem,#a] 2040LDR X,[mem,#x] 2050LDR Y,[mem,#y] 2060LDR SP,[mem,#sp] : ORR SP,SP,#1 2070LDR F,[mem,#f] 2080LDR zpc,[mem,#pc_store] 2090 2100BL recalc_wrap 2110LDRB R0,[mem,#patch_on] 2120AND R0,R0,#%111 2130BIC F,F,#&FF00 2140ORR F,F,R0,LSL#8 2150 2160MOV time,#0 2170 2180LDRB R0,fe08_read 2190BIC R0,R0,#&81 2200STRB R0,fe08_read 2210 2220ADR R0,0 2230TST F,#%1000 2240LDREQ table,opco_addr 2250LDRNE table,bcd_addr 2260ADD table,table,R0 2270;SWI "6502_ReInit" 2280;SWI "6502_UpdateScreen 2290BL poke_updatepixelV 2300BL updatescreen 2310B fetch2 2320 2330.reset_bcdflag 2340ADR R1,0 2350TST F,#%1000 2360LDREQ table,opco_addr 2370LDRNE table,bcd_addr 2380ADD table,table,R1 2390MOV PC,R14 2400 2410.block1 2420EQUD 149 : EQUD -1 2430.block2 2440EQUD 0 : EQUD 0 2450 2460.screen_count 2470EQUD 0 2480EQUD 0 2490 2500.reg_comp 2510EQUD &F4DF << 16 2520 2530.trace_on 2540MOV R12,#1 2550STRB R12,trace 2560MOV PC,R14 2570 2580.show_regs 2590 2600CMP zpc,#&8000 << 16 2610MOVHS PC,R14 2620 2630LDRB R0,trace2 2640CMP R0,#1 2650BEQ trace_skip 2660;MOVNE PC,R14 2670 2680;LDR R0,reg_comp 2690;CMP R0,zpc 2700;SWIEQ &100+ASC"X" 2710;MOVNE PC,R14 2720 2730SWI "6502_Checkkdata" 2740CMP R0,#&1F ; Insert 2750MOVEQ R1,#1 2760STREQ R1,trace2 2770 2780MOV PC,R14 2790 2800MOVEQ R0,#1 2810STREQB R0,trace 2820 2830LDRB R0,trace 2840CMP R0,#1 2850MOVNE PC,14 2860 2870.trace_skip 2880FNshowregs 2890MOV PC,R14 2900 2910 2920 2930.keychk 2940EQUD 0 2950 2960.fetch2 2970 2980LDR R0,[mem,#min] 2990SUB R0,R0,time 3000LDR R1,[mem,#sound_timer] 3010SUB R1,R1,R0 3020STR R1,[mem,#sound_timer] 3030 3040 3050MOV R0,#0 : STR R0,keychk 3060LDR R0,[mem,#min] 3070SUB R0,R0,time ; *** 3080LDR R1,[mem,#screen] 3090SUBS R1,R1,R0 3100STRGT R1,[mem,#screen] 3110BLLE vsync 3120 3130LDR R0,[mem,#min] 3140SUB R0,R0,time ; *** 3150LDR R1,speed 3160SUBS R1,R1,R0 3170STRGT R1,speed 3180BLLE speed_control 3190 3200; LDR R0,[mem,#T1mode] 3210; TST R0,#%1 3220; BEQ skip_timer1 3230 3240LDR R0,[mem,#min] 3250SUB R0,R0,time ; *** 3260LDR R1,[mem,#T1] 3270SUBS R1,R1,R0 3280STRGT R1,[mem,#T1] 3290BLLE timer1 3300.skip_timer1 3310 3320LDR R0,[mem,#min] 3330SUB R0,R0,time 3340LDR R1,[mem,#tape_count] 3350SUBS R1,R1,R0 3360STRGT R1,[mem,#tape_count] 3370BLLE tape_fetch 3380 3390 3400TST F,#%100 3410BNE skip_do_interrupt 3420 3430;.do_interrupt 3440 3450LDRB R1,[mem,#Eifr] 3460;TST R1,#%1000000 3470;SWINE &100+ASC"6" 3480AND R1,R1,#%01111100 3490 3500 3510;AND R1,R1,#%01110000 ; ???????????????? 3520 3530 3540 3550LDRB R2,[mem,#Eier] 3560 3570ANDS R1,R1,R2 3580 3590;TST R1,#%1000000 3600;SWINE &100+ASC"6" 3610;TST R1,#%100000 3620;SWINE &100+ASC"5" 3630;TST R1,#%10000 3640;SWINE &100+ASC"4" 3650;TST R1,#%1000 3660 3670;SWINE &100+ASC"3" 3680;TST R1,#%100 3690;SWINE &100+ASC"2" 3700;CMP R1,#0 3710 3720BEQ skip_do_interrupt 3730 3740.do_interrupt 3750FNdo_interrupt 3760 3770.skip_do_interrupt 3780 3790;BL keyboard MOVED TO CLI!!! 3800BL keys2 3810.skip_keys 3820LDR time,[mem,#T1] 3830;MOV time,time,LSR#15 3840LDR R1,[mem,#screen] 3850CMP R1,#0 : MOVEQ R1,time 3860CMP R1,time 3870MOVLT time,R1 3880 3890LDR R1,[mem,#tape_count] 3900CMP R1,time 3910MOVLT time,R1 3920 3930CMP time,#0 : MOVEQ time,#1 3940STR time,[mem,#min] 3950FNfetch2 3960 3970.interrupt ; called by CLI 3980MOV PC,R14 3990 4000LDRB R1,[mem,#Eifr] 4010;AND R1,R1,#%00110000 4020LDRB R2,[mem,#Eier] 4030 4040ANDS R1,R1,R2 4050MOVEQ PC,R14 4060 4070;TST R1,#%100000 4080;SWINE &100+ASC"5" 4090;TST R1,#%1000000 4100;SWINE &100+ASC"6" 4110 4120FNdo_interrupt 4130 4140MOV PC,R14 4150 4160.F10temp 4170EQUD 0 4180 4190.F10 4200SWI "6502_Getkdata" 4210STR R14,F10temp 4220MOV R0,#255 4230STRB R0,[mem,#lastmode] 4240BL updatescreen 4250;BL force_update_pal 4260LDR PC,F10temp 4270 4280;.fetch3 4290.keys2 4300SWI "6502_Checkkdata" 4310CMP R0,#&1F ; Insert 4320MOVEQ R1,#1 4330STREQ R1,trace2 4340CMP R0,#10 ; F10 4350BEQ F10 4360CMP R0,#11 ; F11 4370CMPNE R0,#12 ; F12 4380CMPNE R0,#15 ; break 4390BEQ raw_exit2 4400MOV PC,R14 4410 4420.keyboard ; called by CLI 4430 4440MOV R0,#1 : STR R0,keychk 4450SWI "6502_Getkdata" 4460CMP R0,#&FF : MOVEQ PC,R14 4470CMP R0,#&1F ; Insert 4480MOVEQ R1,#1 4490STREQ R1,trace2 4500CMP R0,#10 ; F10 4510BEQ F10 4520CMP R0,#15 4530CMPNE R0,#12 4540CMPNE R0,#11 ; F11 4550BEQ raw_exit 4560 4570;CMP R0,#0 ; escape 4580;LDREQB R0,[mem,#&FF] 4590;ORREQ R0,R0,#&80 4600;STREQB R0,[mem,#&FF] 4610LDRB R0,[R1,R0] 4620CMP R0,#&FF 4630;BEQ not_keyboard 4640MOVEQ PC,R14 4650 4660;B not_keyboard 4670CMP R0,#10 ; shift, ctrl 4680MOVLT PC,R14 4690LDRB R1,[mem,#ifr] 4700ORR R1,R1,#%1 ; interrupt is from keyboard 4710STRB R1,[mem,#ifr] 4720LDRB R0,[mem,#ier] 4730TST R0,#%1 4740MOVEQ PC,R14 4750FNdo_interrupt 4760MOV PC,R14 4770 4780 4790 4800.mono_time 4810EQUD 0 4820.speed 4830EQUD 0 4840 4850.speed_control 4860LDR R0,[mem,#speedR] 4870ADD R1,R1,R0 4880STR R1,speed 4890 4900LDR R1,mono_time 4910.mono_loop 4920SWI "OS_ReadMonotonicTime" 4930MOV R0,R0,LSR#1 4940CMP R0,R1 4950BEQ mono_loop 4960STR R0,mono_time 4970 4980MOV PC,R14 4990 5000.vsync 5010STR R14,vsyncR14 5020;MOV R0,#19 5030;SWI "OS_Byte" 5040 5050;LDRB R0,ldrb40_tamper 5060;CMP R0,#1 : ;BLEQ ldrb40_update 5070 5080 5090LDR R0,[mem,#speedR] ; screenR 5100ADD R1,R1,R0 5110STR R1,[mem,#screen] 5120 5130 5140;BL trace_on 5150 5160;LDRB R1,screen_count 5170;SUBS R1,R1,#1 5180;LDRMIB R1,screen_count+4 5190;STRB R1,screen_count 5200LDR R0,[mem,#tamper] 5210CMP R0,#0 5220 5230BEQ no_tamper 5240MOV R0,#0 5250STR R0,[mem,#tamper] 5260;SWI "6502_UpdateScreen" 5270BL recalc_wrap 5280BL updatescreen 5290TST F,#1 << 10 ; cursor on? 5300;BLNE define_cursor 5310;BLNE cursor 5320.no_tamper 5330LDRB R0,[mem,#pal_tamper] 5340CMP R0,#0 5350BLNE update_pal 5360 5370 5380LDR R0,[mem,#cursor_tamper] 5390CMP R0,#0 5400;BLNE cursor 5410 5420 5430;SUB R0,mem,#512 ; sheila 5440;LDRB R1,[R0,#&20] 5450;TST R1,#%10 ; teletext? 5460;SWINE "6502_UpdateScreen" 5470;BLNE updatescreen 5480;ADD R0,R0,#&4D 5490;LDRB R1,[R0] 5500;LDRB R2,[R0,#1] 5510 5520 5530 5540LDRB R1,[mem,#Eifr] 5550ORR R1,R1,#%100 ; interrupt is from vsync 5560STRB R1,[mem,#Eifr] 5570 5580;TST F,#1 << 9 5590;BEQ skip_exact 5600 5610;LDR R1,mono_time 5620;.mono_loop 5630;SWI "OS_ReadMonotonicTime" 5640;MOV R0,R0,LSR#1 5650;CMP R0,R1 5660;BEQ mono_loop 5670;STR R0,mono_time 5680 5690.skip_exact 5700 5710LDR PC,vsyncR14 5720.vsyncR14 5730EQUD 0 5740 5750 5760 5770.timer1 5780LDR R0,[mem,#speedR] ; was T1R 5790ADD R1,R1,R0 5800STR R1,[mem,#T1] 5810 5820LDRB R1,[mem,#Eifr] 5830ORR R1,R1,#%1000 ; interrupt is from RTC 5840STRB R1,[mem,#Eifr] 5850 5860MOV PC,R14 5870 5880 5890 5900;.trace2 5910;EQUD 0 5920 5930.reset 5940;MOV R1,#1 5950;STR R1,trace 5960MOV R0,#15 : MOV R1,#0 : SWI "OS_Byte" 5970MOV R0,#&10000 5980SUB R0,R0,#4 5990LDR R0,[mem,R0] 6000MOV zpc,R0,LSL#16 6010BIC F,F,#%1000 ; clear Decimal mode 6020ORR F,F,#%100 ; set interrupt disable 6030FNfetch2 6040 6050 6060.exit 6070MOV R0,#0 6080.raw_exit2 6090SWI "6502_Getkdata" 6100.raw_exit 6110STR A,[mem,#a] 6120STR X,[mem,#x] 6130STR Y,[mem,#y] 6140STR SP,[mem,#sp] 6150STR F,[mem,#f] 6160STR zpc,[mem,#pc_store] 6170LDR R13,return_addr 6180LDMFD R13!,{R1-R12,PC} 6190;MOV PC,R14 6200 6210.return_addr 6220EQUD 0 6230 6240.roms_addr 6250EQUD 0 6260 6270 6280.fe08_read 6290.casette_read 6300EQUB 0 6310.fe08_write 6320EQUB 0 6330.fe09 6340EQUB 0 6350;.fe10 6360;EQUB 0 6370ALIGN 6380.tbuffer 6390EQUD 0 6400 6410.read_tape_data 6420LDRB R0,[mem,#Eifr] 6430BIC R0,R0,#%10000 6440 6450STRB R0,[mem,#Eifr] 6460LDRB R0,fe09 6470;CMP R0,#ASC"*" 6480;SWIEQ &100+ASC"h" 6490;SWINE &100+ASC"H" 6500;MOV R0,#ASC"*" 6510 6520MOV PC,R14 6530 6540.tape_fetch 6550;SWI &100+ASC"b" 6560;LDR R0,[mem,#tapeR] 6570;MOV R0,#&3400 ; 2000000/(1200/8)~=1200 baud 6580MOV R0,#&6000 6590ADDS R1,R1,R0 6600MOVLE R1,#&6000 6610 6620LDR R0,[mem,#Elatch] 6630TST R0,#%110 ; casette input mode? 6640MOVNE R1,#&100000 6650 6660TST R0,#%1000000 ; is *Motor on? 6670MOVEQ R1,#&100000 6680 6690STR R1,[mem,#tape_count] 6700 6710MOVEQ PC,R14 6720 6730LDRB R1,[mem,#tape_handle] 6740CMP R1,#0 6750MOVEQ PC,R14 6760 6770.tape_get 6780;SWI &100+ASC"B" 6790SWI "XOS_BGet" 6800MOVVS R1,#0 6810STRVSB R1,[mem,#tape_handle] 6820MOVVS PC,R14 6830 6840BCC tape_skip10 6850 6860MOV R0,#1 6870MOV R2,#0 6880SWI "XOS_Args" ; rewind tape to start 6890MOVVS R1,#0 6900STRVSB R1,[mem,#tape_handle] 6910MOVVS PC,R14 6920 6930.tape_skip10 6940;CMP R0,#ASC"*" 6950;SWIEQ &100+ASC"*" 6960 6970CMP R0,#&FF 6980BNE not_FF 6990SWIEQ "XOS_BGet" 7000CMP R0,#&FF 7010BEQ not_FF 7020 7030;MOV R0,R0,LSL#4 7040 7050;LDRB R1,fe08_read 7060LDRB R1,[mem,#Eifr] 7070 7080TST R0,#%100 7090BICEQ R1,R1,#%1000000 7100ORRNE R1,R1,#%1000000 7110 7120STRB R1,[mem,#Eifr] 7130 7140MOVEQ PC,R14 7150 7160LDRB R0,[mem,#ier] 7170TST R0,#%1000000 7180MOVEQ PC,R14 7190 7200;ORR R1,R1,#&80 7210;STRB R1,fe08_read 7220;SWI &100+ASC"F" 7230B do_interrupt 7240;B interrupt 7250;B skip_do_interrupt 7260 7270.not_FF 7280STRB R0,fe09 7290 7300;SWI &100+ASC"B" 7310 7320;LDRB R0,fe08_write 7330;TST R0,#&80 ; receive interrupt enable bit 7340;MOVEQ PC,R14 7350 7360;LDRB R0,fe08_read 7370;ORR R0,R0,#&81 7380;STRB R0,fe08_read 7390LDRB R0,[mem,#Eifr] 7400ORR R0,R0,#%10000 7410STRB R0,[mem,#Eifr] 7420 7430;LDRB R12,[mem,#&C2] 7440;MOV R12,R12,LSL#24 7450;FNprint2(12) 7460;SWI &100+ASC" " 7470 7480LDRB R0,[mem,#Eier] 7490TST R0,#%10000 ; receive interrupt enable bit 7500;SWIEQ &100+ASC"Q" 7510;MOVEQ PC,R14 7520;SWI &100+ASC"i" 7530B do_interrupt 7540;B interrupt 7550;MOV PC,R14 7560 7570.dummy 7580MOV PC,R14 7590 7600 7610.strb8000 ; greater than 8000 7620] 7630IF master THEN 7640[OPTp 7650CMP R1,#&E000 7660BGE strb_rom_ret 7670CMP R1,#&C000 7680BGE strb_rom_ret2 7690CMP R1,#&9000 7700BGE strb_rom 7710] 7720ELSE 7730[OPTp 7740CMP R1,#&C000 7750BGE strb_rom_ret 7760] 7770ENDIF 7780[OPTp 7790 7800LDRB R12,[mem,#rom] 7810TST R12,#&80 7820BEQ strb_rom 7830 7840;SUB R13,mem,#(&8000+&B000) ; 4k Private RAM 7850;STRB R0,[R13,R1] 7860STRB R0,[mem,R1] 7870MOV PC,R14 7880 7890.strb_rom 7900SUB R12,mem,#-ROMRAM 7910LDRB R13,[mem,#rom] 7920LDRB R13,[R12,R13] 7930CMP R13,#0 7940STREQB R0,[mem,R1] 7950MOV PC,R14 7960;B strb_rom_ret 7970 7980.romsel 7990LDRB R12,[mem,#ROMSEL_ON] 8000CMP R12,#0 8010MOVNE PC,R14 8020 8030LDRB R1,[mem,#rom] 8040 8050LDR R12,roms_addr 8060AND R2,R0,#&F ; socket number 8070LDRB R1,[mem,#rom] 8080CMP R2,R1:MOVEQ PC,R14 8090AND R1,R1,#&F 8100AND R0,R0,#&F 8110STRB R0,[mem,#rom] 8120SUB R13,mem,#-ROMRAM 8130LDRB R13,[R13,R1] 8140CMP R13,#0 ; is the bank being paged out RAM? 8150BNE romsel2 8160 8170TST R0,#%10000000 ; private RAM mapped in? 8180MOVEQ R13,#&8000 8190MOVNE R13,#&9000 8200AND R0,R0,#&F 8210 8220ADD R2,R12,R1,LSL#14 8230ADDNE R2,R2,#&1000 8240ADD R12,R12,R0,LSL#14 ; R0*16*1024 8250ADDNE R12,R12,#&1000 8260ADR R1,romsel_loop_temp 8270STMIA R1,{R0,R4-R8,R14} 8280ADD mem,mem,R13 8290RSB R13,R13,#&C000 8300.romsel_loop 8310LDMIA mem,{R0,R1,R4,R5,R6,R7,R8,R14} 8320STMIA R2!,{R0,R1,R4,R5,R6,R7,R8,R14} 8330LDMIA R12!,{R0,R1,R4,R5,R6,R7,R8,R14} 8340STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R14} 8350SUBS R13,R13,#4*8 8360BNE romsel_loop 8370SUB mem,mem,#&C000 8380ADR R1,romsel_loop_temp 8390LDMIA R1,{R0,R4-R8,PC} 8400.romsel_loop_temp 8410EQUD 0:EQUD 0:EQUD 0:EQUD 0 8420EQUD 0:EQUD 0:EQUD 0:EQUD 0 8430 8440.romsel_empty 8450ADD R13,R2,R2,LSL#8 8460ADD R13,R13,R13,LSL#16 8470ADD R0,mem,#&8000 8480STR R13,[R0,#0] 8490STR R13,[R0,#4] 8500STR R13,[R0,#8] 8510STR R13,[R0,#12] 8520MOV PC,R14 8530 8540.romsel2 8550 8560SUB R13,mem,#-ROMRAM 8570LDRB R13,[R13,R2] 8580CMP R13,#2 ; is the bank being paged out empty? 8590BEQ romsel_empty 8600 8610TST R0,#%10000000 ; private RAM mapped in? 8620MOVEQ R13,#&8000 8630MOVNE R13,#&9000 8640AND R0,R0,#&F 8650 8660 8670ADD R12,R12,R0,LSL#14 ; R0*16*1024 8680ADDNE R12,R12,#&1000 8690ADD mem,mem,R13 8700RSB R13,R13,#&C000 8710ADR R1,romsel_loop_temp 8720STMIA R1,{R0,R4-R8,R14} 8730.romsel2_loop 8740LDMIA R12 !,{R0,R1,R4,R5,R6,R7,R8,R14} 8750STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R14} 8760;LDR R1,[R12],#4 8770;STR R1,[mem],#4 ; store byte from ROM in main memory map 8780SUBS R13,R13,#4*8 8790BNE romsel2_loop 8800SUB mem,mem,#&C000 8810ADR R1,romsel_loop_temp 8820LDMIA R1,{R0,R4-R8,PC} 8830 8840.link 8850EQUD 0 8860 8870FNscreen 8880 8890.write_palette 8900AND R1,R1,#7 8910SUB R12,mem,#-pal_regs 8920LDRB R2,[R12,R1] 8930CMP R0,R2:MOVEQ PC,R14 8940STRB R0,[R12,R1] 8950 8960LDR R1,[mem,#Palette] 8970CMP R1,#0 8980MOVNE PC,R14 8990 9000MOV R1,#255:STRB R1,[mem,#pal_tamper] 9010MOV PC,R14 9020 9030.update_pal 9040LDR R1,[mem,#Palette] 9050CMP R1,#0 9060MOVNE PC,R14 9070.force_update_pal 9080LDRB R1,[mem,#fe20] 9090;TST R1,#%10 9100;MOVNE PC,R14 ; mode 7 9110AND R1,R1,#%11100 9120CMP R1,#%11100 : BEQ twocolpal 9130CMP R1,#%01000 : BEQ twocolpal 9140CMP R1,#%11000 : BEQ fourcolpal 9150CMP R1,#%00100 : BEQ fourcolpal 9160 9170 9180.sixteencolpal 9190LDRB R1,[mem,#pal_regs+0] 9200LDRB R2,[mem,#pal_regs+1] 9210 9220MOV R0,#0 9230TST R2,#%1 ; r0 9240ORREQ R0,R0,#%1 9250TST R2,#%10000 ; g0 9260ORREQ R0,R0,#%10 9270TST R1,#%10000 ; b0 9280ORREQ R0,R0,#%100 9290 9300SWI &100+19 9310SWI &100+0 9320SWI "OS_WriteC" 9330SWI &100 9340SWI &100 9350SWI &100 9360 9370MOV R0,#0 9380TST R2,#%10 ; r2 9390ORREQ R0,R0,#%1 9400TST R2,#%100000 ; g2 9410ORREQ R0,R0,#%10 9420TST R1,#%100000 ; b2 9430ORREQ R0,R0,#%100 9440 9450SWI &100+19 9460SWI &100+2 9470SWI "OS_WriteC" 9480SWI &100 9490SWI &100 9500SWI &100 9510 9520MOV R0,#0 9530TST R2,#%100 ; r8 9540ORREQ R0,R0,#%1 9550TST R1,#%100 ; g8 9560ORREQ R0,R0,#%10 9570TST R1,#%1000000 ; b8 9580ORREQ R0,R0,#%100 9590 9600SWI &100+19 9610SWI &100+8 9620SWI "OS_WriteC" 9630SWI &100 9640SWI &100 9650SWI &100 9660 9670MOV R0,#0 9680TST R2,#%1000 ; r10 9690ORREQ R0,R0,#%1 9700TST R1,#%1000 ; g10 9710ORREQ R0,R0,#%10 9720TST R1,#%10000000 ; b10 9730ORREQ R0,R0,#%100 9740 9750SWI &100+19 9760SWI &100+10 9770SWI "OS_WriteC" 9780SWI &100 9790SWI &100 9800SWI &100 9810 9820LDRB R1,[mem,#pal_regs+2] 9830LDRB R2,[mem,#pal_regs+3] 9840 9850MOV R0,#0 9860TST R2,#%1 ; r4 9870ORREQ R0,R0,#%1 9880TST R2,#%10000 ; g4 9890ORREQ R0,R0,#%10 9900TST R1,#%10000 ; b4 9910ORREQ R0,R0,#%100 9920 9930SWI &100+19 9940SWI &100+4 9950SWI "OS_WriteC" 9960SWI &100 9970SWI &100 9980SWI &100 9990 10000MOV R0,#0 10010TST R2,#%10 ; r6 10020ORREQ R0,R0,#%1 10030TST R2,#%100000 ; g6 10040ORREQ R0,R0,#%10 10050TST R1,#%100000 ; b6 10060ORREQ R0,R0,#%100 10070 10080SWI &100+19 10090SWI &100+6 10100SWI "OS_WriteC" 10110SWI &100 10120SWI &100 10130SWI &100 10140 10150MOV R0,#0 10160TST R2,#%100 ; r12 10170ORREQ R0,R0,#%1 10180TST R1,#%100 ; g12 10190ORREQ R0,R0,#%10 10200TST R1,#%1000000 ; b12 10210ORREQ R0,R0,#%100 10220 10230SWI &100+19 10240SWI &100+12 10250SWI "OS_WriteC" 10260SWI &100 10270SWI &100 10280SWI &100 10290 10300MOV R0,#0 10310TST R2,#%1000 ; r14 10320ORREQ R0,R0,#%1 10330TST R1,#%1000 ; g14 10340ORREQ R0,R0,#%10 10350TST R1,#%10000000 ; b14 10360ORREQ R0,R0,#%100 10370 10380SWI &100+19 10390SWI &100+14 10400SWI "OS_WriteC" 10410SWI &100 10420SWI &100 10430SWI &100 10440 10450LDRB R1,[mem,#pal_regs+4] 10460LDRB R2,[mem,#pal_regs+5] 10470 10480MOV R0,#0 10490TST R2,#%1 ; r5 10500ORREQ R0,R0,#%1 10510TST R2,#%10000 ; g5 10520ORREQ R0,R0,#%10 10530TST R1,#%10000 ; b5 10540ORREQ R0,R0,#%100 10550 10560SWI &100+19 10570SWI &100+5 10580SWI "OS_WriteC" 10590SWI &100 10600SWI &100 10610SWI &100 10620 10630MOV R0,#0 10640TST R2,#%10 ; r7 10650ORREQ R0,R0,#%1 10660TST R2,#%100000 ; g7 10670ORREQ R0,R0,#%10 10680TST R1,#%100000 ; b7 10690ORREQ R0,R0,#%100 10700 10710SWI &100+19 10720SWI &100+7 10730SWI "OS_WriteC" 10740SWI &100 10750SWI &100 10760SWI &100 10770 10780MOV R0,#0 10790TST R2,#%100 ; r13 10800ORREQ R0,R0,#%1 10810TST R1,#%100 ; g13 10820ORREQ R0,R0,#%10 10830TST R1,#%1000000 ; b13 10840ORREQ R0,R0,#%100 10850 10860SWI &100+19 10870SWI &100+13 10880SWI "OS_WriteC" 10890SWI &100 10900SWI &100 10910SWI &100 10920 10930MOV R0,#0 10940TST R2,#%1000 ; r15 10950ORREQ R0,R0,#%1 10960TST R1,#%1000 ; g15 10970ORREQ R0,R0,#%10 10980TST R1,#%10000000 ; b15 10990ORREQ R0,R0,#%100 11000 11010SWI &100+19 11020SWI &100+15 11030SWI "OS_WriteC" 11040SWI &100 11050SWI &100 11060SWI &100 11070 11080LDRB R1,[mem,#pal_regs+6] 11090LDRB R2,[mem,#pal_regs+7] 11100 11110MOV R0,#0 11120TST R2,#%1 ; r1 11130ORREQ R0,R0,#%1 11140TST R2,#%10000 ; g1 11150ORREQ R0,R0,#%10 11160TST R1,#%10000 ; b1 11170ORREQ R0,R0,#%100 11180 11190SWI &100+19 11200SWI &100+1 11210SWI "OS_WriteC" 11220SWI &100 11230SWI &100 11240SWI &100 11250 11260MOV R0,#0 11270TST R2,#%10 ; r3 11280ORREQ R0,R0,#%1 11290TST R2,#%100000 ; g3 11300ORREQ R0,R0,#%10 11310TST R1,#%100000 ; b3 11320ORREQ R0,R0,#%100 11330 11340SWI &100+19 11350SWI &100+3 11360SWI "OS_WriteC" 11370SWI &100 11380SWI &100 11390SWI &100 11400 11410MOV R0,#0 11420TST R2,#%100 ; r9 11430ORREQ R0,R0,#%1 11440TST R1,#%100 ; g9 11450ORREQ R0,R0,#%10 11460TST R1,#%1000000 ; b9 11470ORREQ R0,R0,#%100 11480 11490SWI &100+19 11500SWI &100+9 11510SWI "OS_WriteC" 11520SWI &100 11530SWI &100 11540SWI &100 11550 11560MOV R0,#0 11570TST R2,#%1000 ; r11 11580ORREQ R0,R0,#%1 11590TST R1,#%1000 ; g11 11600ORREQ R0,R0,#%10 11610TST R1,#%10000000 ; b11 11620ORREQ R0,R0,#%100 11630 11640SWI &100+19 11650SWI &100+11 11660SWI "OS_WriteC" 11670SWI &100 11680SWI &100 11690SWI &100 11700 11710MOV PC,R14 11720 11730.twocolpal 11740LDRB R1,[mem,#pal_regs+0] 11750LDRB R2,[mem,#pal_regs+1] 11760MOV R0,#0 11770TST R2,#%1 ; r0 11780ORREQ R0,R0,#%1 11790TST R2,#%10000 ; g0 11800ORREQ R0,R0,#%10 11810TST R1,#%10000 ; b0 11820ORREQ R0,R0,#%100 11830 11840SWI &100+19 11850SWI &100+0 11860SWI "OS_WriteC" 11870SWI &100 11880SWI &100 11890SWI &100 11900 11910MOV R0,#0 11920TST R2,#%100 ; r1 11930ORREQ R0,R0,#%1 11940TST R1,#%100 ; g1 11950ORREQ R0,R0,#%10 11960TST R1,#%1000000 ; b1 11970ORREQ R0,R0,#%100 11980 11990SWI &100+19 12000SWI &100+3 ; mode 4 fix 12010SWI "OS_WriteC" 12020SWI &100 12030SWI &100 12040SWI &100 12050MOV PC,R14 12060 12070.fourcolpal 12080LDRB R1,[mem,#pal_regs+0] 12090LDRB R2,[mem,#pal_regs+1] 12100MOV R0,#0 12110TST R2,#%1 ; r0 12120ORREQ R0,R0,#%1 12130TST R2,#%10000 ; g0 12140ORREQ R0,R0,#%10 12150TST R1,#%10000 ; b0 12160ORREQ R0,R0,#%100 12170 12180SWI &100+19 12190SWI &100+0 12200SWI "OS_WriteC" 12210SWI &100 12220SWI &100 12230SWI &100 12240 12250MOV R0,#0 12260TST R2,#%10 ; r1 12270ORREQ R0,R0,#%1 12280TST R2,#%100000 ; g1 12290ORREQ R0,R0,#%10 12300TST R1,#%100000 ; b1 12310ORREQ R0,R0,#%100 12320 12330SWI &100+19 12340SWI &100+1 12350SWI "OS_WriteC" 12360SWI &100 12370SWI &100 12380SWI &100 12390 12400MOV R0,#0 12410TST R2,#%100 ; r2 12420ORREQ R0,R0,#%1 12430TST R1,#%100 ; g2 12440ORREQ R0,R0,#%10 12450TST R1,#%1000000 ; b2 12460ORREQ R0,R0,#%100 12470 12480SWI &100+19 12490SWI &100+2 12500SWI "OS_WriteC" 12510SWI &100 12520SWI &100 12530SWI &100 12540 12550MOV R0,#0 12560TST R2,#%1000 ; r3 12570ORREQ R0,R0,#%1 12580TST R1,#%1000 ; g3 12590ORREQ R0,R0,#%10 12600TST R1,#%10000000 ; b3 12610ORREQ R0,R0,#%100 12620 12630SWI &100+19 12640SWI &100+3 12650SWI "OS_WriteC" 12660SWI &100 12670SWI &100 12680SWI &100 12690 12700MOV PC,R14 12710 12720.write_screen_start_low 12730AND R0,R0,#%11100000 12740STRB R0,[mem,#crt_regs+13] 12750MOV R0,#1 : STRB R0,[mem,#tamper] 12760MOV PC,R14 12770 12780.read_screen_start_low 12790LDRB R0,[mem,#crt_regs+13] 12800MOV PC,R14 12810 12820.write_screen_start_high 12830AND R0,R0,#%00111111 12840STRB R0,[mem,#crt_regs+12] 12850MOV R0,#1 : STRB R0,[mem,#tamper] 12860MOV PC,R14 12870 12880.read_screen_start_high 12890LDRB R0,[mem,#crt_regs+12] 12900MOV PC,R14 12910 12920.write_iscr ; &FE00 12930 12940LDRB R1,[mem,#Eier] 12950 12960TST R0,#&80 12970ORREQ R1,R1,R0 12980BICNE R1,R1,R0 12990AND R1,R1,#%01111100 13000STRB R1,[mem,#Eier] 13010MOV PC,R14 13020 13030 13040 13050TST R0,#&80 13060;SWIEQ &100+ASC"[" 13070;SWINE &100+ASC"]" 13080AND R0,R0,#%01111100 13090STRB R0,[mem,#Eier] 13100;SWI &100+ASC"[" 13110;MOV R12,R0,LSL#24 13120;FNprint2(12) 13130MOV PC,R14 13140 13150.read_iscr ; &FE00 13160LDRB R0,[mem,#Eifr] 13170BIC R1,R0,#%10 13180STRB R1,[mem,#Eifr] 13190 13200;LDRB R1,[mem,#Eier] 13210;ANDS R1,R1,R0 13220BICS R1,R0,#%11 13230ORRNE R0,R0,#%1 ; master IRQ bit 13240 13250;BIC R0,R0,#%1000000 13260;LDRB R1,[mem,#&C2] 13270;CMP R1,#1 13280;ORREQ R0,R0,#%1000000 13290;CMP R1,#2 13300;BICEQ R0,R0,#%1000000 13310;ORREQ R0,R0,#%1000000 13320 13330MOV PC,R14 13340 13350.recalc_wrap 13360LDRB R0,[mem,#Elatch] 13370AND R0,R0,#%00111000 ; screen mode 13380MOV R0,R0,LSR#1 13390ADR R1,mode_table 13400LDR R0,[R1,R0] 13410 13420BIC F,F,#&FF000000 13430BIC F,F,#&00FF0000 13440ORR F,F,R0,LSL#16 ; wrap_addr 13450 13460MOV PC,R14 13470 13480.counter_last 13490EQUD 0 13500 13510.write_counter 13520LDRB R1,R14store+4 13530CMP R0,R1:MOVEQ PC,R14 13540 13550STR R14,R14store 13560ADD R0,R0,#1 13570STRB R0,R14store+4 13580 13590LDR R0,[mem,#min] 13600SUB R0,R0,time 13610LDR R1,[mem,#sound_timer] 13620SUB R1,R1,R0 13630LDR R2,counter_last 13640STR R1,counter_last 13650SUB R1,R2,R1 13660CMP R1,#200 13670;SWILT &100+ASC"s" 13680BGE skip_noise 13690 13700MOV R0,#%11100100 ; low frequency noise 13710STRB R0,sound_data 13720MOV R0,#0 : BL sound_latch 13730MOV R0,#%11110000 ; maximum volume noise 13740STRB R0,sound_data 13750MOV R0,#0 : BL sound_latch 13760MOV R0,#%11011111 ; channel 1 volume 0 13770STRB R0,sound_data 13780MOV R0,#0 : BL sound_latch 13790 13800LDR PC,R14store 13810;B skip_noise2 13820 13830.skip_noise 13840MOV R0,#%11111111 ; noise volume 0 13850STRB R0,sound_data 13860MOV R0,#0 : BL sound_latch 13870 13880.skip_noise2 13890LDRB R0,R14store+4 13900 13910MOV R0,R0,LSL#2 13920AND R0,R0,#%1111 13930ORR R0,R0,#%11000000 ; tone 1 freq 13940STRB R0,sound_data 13950MOV R0,#0 13960BL sound_latch 13970LDRB R0,R14store+4 13980MOV R0,R0,LSR#2 13990STRB R0,sound_data 14000LDR R14,R14store 14010MOV R0,#0 14020B sound_latch 14030 14040.R14store 14050EQUD 0 14060EQUD 0 14070 14080.write_latch 14090STRB R0,[mem,#Elatch] 14100 14110STR R14,R14store 14120TST R0,#%10 14130MOVEQ R0,#%11011111 ; channel 1 volume 0 14140MOVNE R0,#%11010000 ; channel 1 volume 15 14150STRB R0,sound_data 14160MOV R0,#0 14170BL sound_latch 14180 14190MOV R0,#%11111111 ; noise volume 0 14200STRB R0,sound_data 14210MOV R0,#0 : BL sound_latch 14220 14230LDR R14,R14store 14240LDRB R0,[mem,#Elatch] 14250 14260AND R0,R0,#%00111000 ; screen mode 14270LDRB R1,mode 14280CMP R0,R1 14290MOVEQ PC,R14 14300STRB R0,mode 14310 14320MOV R1,#1 : STRB R1,[mem,#tamper] 14330 14340CMP R0,#7 << 3 14350ORREQ F,F,#1 << 12 14360BICNE F,F,#1 << 12 14370SWIEQ &100+12 14380 14390CMP R0,#3 << 3 14400MOVLE R1,#80 14410MOVGT R1,#40 14420STRB R1,[mem,#crt_regs+1] ; horizontal characters 14430MOV R0,R0,LSR#1 14440ADR R1,mode_table 14450LDR R0,[R1,R0] 14460 14470BIC F,F,#&FF000000 14480BIC F,F,#&00FF0000 14490ORR F,F,R0,LSL#16 ; wrap_addr 14500 14510MOV R0,R0,LSR#16 14520AND R1,R0,#&FF 14530STRB R1,[mem,#crt_regs+6] ; vertical characters 14540MOV R1,#&24 14550STRB R1,[mem,#crt_regs+3] ; misc. 14560MOV R0,R0,LSR#8 14570STRB R0,[mem,#fe20] 14580B poke_updatepixelV ; includes MOV PC,R14 14590 14600.mode 14610EQUD 0 14620 14630.mode_table 14640EQUD &9C203000 ; mode 0 14650EQUD &D8203000 ; mode 1 14660EQUD &F4203000 ; mode 2 14670EQUD &9C194000 ; mode 3 14680EQUD &88205800 ; mode 4 14690EQUD &C4205800 ; mode 5 14700EQUD &88196000 ; mode 6 14710EQUD &88196000 ; (mode 7) 14720 14730.read_latch 14740LDRB R0,[mem,#Elatch] 14750MOV PC,R14 14760 14770.write_ROMint 14780STRB R0,[mem,#ROMint] 14790LDRB R1,[mem,#Eifr] 14800TST R0,#%10000 14810BICNE R1,R1,#%100 14820;SWINE &100+ASC"/" 14830TST R0,#%100000 14840BICNE R1,R1,#%1000 14850;SWINE &100+ASC"." 14860TST R0,#%1000000 14870BICNE R1,R1,#%1000000 ; clear (some?) tape interrupts 14880;SWINE &100+ASC"," 14890STRB R1,[mem,#Eifr] 14900AND R0,R0,#%1111 14910CMP R0,#8 14920CMPNE R0,#9 14930ORREQ F,F,#1 << 11 14940BICNE F,F,#1 << 11 14950;SWIEQ &100+ASC"1" 14960;SWINE &100+ASC"0" 14970BNE romsel 14980MOV PC,R14 14990 15000.read_ROMint 15010.read_counter 15020.write_tape_data 15030.read_palette 15040MOV PC,R14 15050 15060FNsound_latch 15070FNsound_misc 15080 15090.osbput 15100MOV R0,A,LSR#24 15110MOV R1,Y,LSR#24 15120SWI "XOS_BPut" 15130BVS swi_error 15140B opcode(&60) ; rts 15150 15160.osbget 15170MOV R0,A,LSR#24 15180MOV R1,Y,LSR#24 15190SWI "XOS_BGet" 15200BVS swi_error 15210MOV A,R0,LSL#24 15220FNsetupC 15230B opcode(&60) ; rts 15240 15250.swi_error 15260ADD mem,mem,#&100 15270ADD mem,mem,#&002 15280MOV R1,#0 ; BRK 15290STRB R1,[mem,#-2] 15300LDRB R1,[R0] ; error no 15310STRB R1,[mem,#-1] 15320ADD R0,R0,#4 15330MOV R14,#0 15340 15350.swi_err_loop 15360LDRB R13,[R0,R14] 15370CMP R13,#0 15380;MOV R13,#ASC"A" 15390STRB R13,[mem,R14] 15400ADD R14,R14,#1 15410MOVEQ R14,#255 15420CMP R14,#253 15430BLE swi_err_loop 15440 15450MOV zpc,#&100 << 16 15460SUB mem,mem,#&100 15470SUB mem,mem,#&002 15480FNfetch2 15490 15500 15510 15520 15530.strb_rom_ret 15540 15550.sheila 15560SUBS R2,R1,#&FE00 15570MOVLT PC,R14 15580SUBS R2,R2,#&100 15590MOVGE PC,R14 15600;BGE FFpage 15610 15620TST time,#%1 15630SUBNE time,time,#1 15640SUBEQ time,time,#2 15650 15660;STRB R0,[mem,R1] 15670BIC R1,R1,#&F0 ; elk 15680SUB R2,mem,#&10000:STRB R0,[R2,R1] 15690 15700AND R2,R1,#&F 15710;ADR R1,sheila_writetab 15720LDR PC,[PC,R2,LSL#2] 15730EQUD 0 ; padding for pipeline 15740.sheila_writetab 15750] 15760FOR II%=0 TO 15 15770[OPTp 15780EQUD write_iscr 15790EQUD dummy 15800EQUD write_screen_start_low 15810EQUD write_screen_start_high 15820EQUD write_tape_data 15830EQUD write_ROMint 15840EQUD write_counter 15850EQUD write_latch 15860FNequd(8,write_palette) 15870] 15880NEXT 15890[OPTp 15900 15910.ldrb_FFpage 15920;SUB time,time,#1 15930MOV PC,R14 15940 15950.ldrb8000 ; greater than 8000 15960 15970CMP R1,#&FE00 15980BHS ldrb_sheila 15990 16000LDRB R0,[mem,R1] 16010MOV PC,R14 16020 16030 16040;MOV R1,R1,LSR#16 16050] 16060IF master THEN 16070[OPTp 16080.ldrb16_8000 ; greater than 8000 16090 16100CMP R1,#&FE00 << 16 16110BHS ldrb16_sheila 16120 16130LDRB R0,[mem,R1,LSR#16] 16140MOV PC,R14 16150 16160.ldrb16_screen 16170CMP R1,#&8000 << 16 16180BHS ldrb16_8000 16190 16200LDRB R12,[mem,#ACCCON] 16210 16220CMP zpc,#&C000 << 16 16230MOVLT R13,R12,LSR#1 16240MOVGE R13,R12 16250CMP zpc,#&E000 << 16 16260MOVGE R13,R12,LSR#1 ; now bit 1 of R13 is what 16270 ; we must look at 16280 16290TST R13,#%10 16300SUBNE R13,mem,#(&3000+&10000) ; shadow screen memory 16310;MOVEQ R13,mem 16320LDRNEB R0,[R13,R1,LSR#16] 16330LDREQB R0,[mem,R1,LSR#16] 16340MOV PC,R14 16350] 16360ELSE 16370[OPTp 16380.ldrb16_screen 16390CMP R1,#&FE00 << 16 16400BHS ldrb16_sheila 16410 16420LDRB R0,[mem,R1,LSR#16] 16430MOV PC,R14 16440] 16450ENDIF 16460 16470IF master THEN 16480[OPTp 16490 16500.ldrb_screen 16510.ldrb3000 ; greater than 3000 16520 16530CMP R1,#&8000 16540BHS ldrb8000 16550 16560LDRB R12,[mem,#ACCCON] 16570 16580CMP zpc,#&C000 << 16 16590MOVLT R13,R12,LSR#1 16600MOVGE R13,R12 16610CMP zpc,#&E000 << 16 16620MOVGE R13,R12,LSR#1 ; now bit 1 of R13 is what 16630 ; we must look at 16640 16650TST R13,#%10 16660SUBNE R13,mem,#(&3000+&10000) ; shadow screen memory 16670;MOVEQ R13,mem 16680LDRNEB R0,[R13,R1] 16690LDREQB R0,[mem,R1] 16700MOV PC,R14 16710] 16720ELSE 16730[OPTp 16740.ldrb_screen 16750.ldrb3000 ; greater than 3000 16760CMP R1,#&FE00 16770BHS ldrb_sheila 16780LDRB R0,[mem,R1] 16790MOV PC,R14 16800] 16810ENDIF 16820 16830[OPTp 16840 16850.ldrb16_sheila 16860MOV R12,R1,LSR#16 16870B ldrb_sheila2 16880 16890.ldrb16_8000 16900MOV R1,R1,LSR#16 16910 16920.ldrb_8000 16930CMP R1,#&FE00 16940BHS ldrb_sheila 16950CMP R1,#&C000 16960MOVHS PC,R14 16970 16980CMP zpc,#&8000<<16 16990BLO key_skip ; fix for stryker's run 17000 17010TST F,#1 << 11 17020MOVEQ PC,R14 17030.key_skip 17040 17050;SWI &100+ASC"K" 17060 17070STMFD mem,{R1-R2,R12-R13} 17080 17090; electron keyboard 17100EOR R0,R1,#&FF 17110EOR R0,R0,#&FF00 17120BIC R0,R0,#%1100000000000000 17130LDR R2,[mem,#key_addr] 17140MOV R12,#&F0 17150 17160LDR R13,[R2,#0] 17170ANDS R13,R13,R0 17180ORRNE R12,R12,#1 17190 17200LDR R13,[R2,#4] 17210ANDS R13,R13,R0 17220ORRNE R12,R12,#2 17230 17240LDR R13,[R2,#8] 17250ANDS R13,R13,R0 17260ORRNE R12,R12,#4 17270 17280LDR R13,[R2,#12] 17290ANDS R13,R13,R0 17300ORRNE R12,R12,#8 17310 17320MOV R0,R12 17330;ANDS R12,R12,#&F 17340;SWINE &100+ASC"K" 17350LDMEA mem,{R1-R2,R12-R13} 17360MOV PC,R14 17370 17380.ldrb_sheila 17390MOV R12,R1 17400 17410.ldrb_sheila2 17420LDRB R0,[mem,R12] 17430 17440SUBS R2,R12,#&FE00 17450MOVLT PC,R14 17460SUBS R2,R2,#&100 17470BGE ldrb_FFpage 17480 17490BIC R12,R12,#&F0 ; elk 17500SUB R2,mem,#&10000:LDRB R0,[R2,R12] 17510 17520SUB time,time,#1 17530 17540AND R2,R12,#&FF 17550;ADR R1,sheila_readtab 17560LDR PC,[PC,R2,LSL#2] 17570EQUD 0 ; padding for pipeline 17580.sheila_readtab 17590] 17600FOR II%=0 TO 15 17610[OPTp 17620EQUD read_iscr 17630EQUD dummy 17640EQUD read_screen_start_low 17650EQUD read_screen_start_high 17660EQUD read_tape_data 17670EQUD read_ROMint 17680EQUD read_counter 17690EQUD read_latch 17700FNequd(8,read_palette) 17710] 17720NEXT 17730[OPTp 17740 17750FNalign16 ; fit into cache better? 17760 17770FNopcodes 17780 17790.patch_screen 17800MOV PC,R14 17810.patch_pixel 17820MOV PC,R14 17830 17840.end 17850] 17860NEXT 17870OSCLI"Load <6502Em$Dir>.SRC.revtable "+STR$~(code+mode0tab) 17880OSCLI"Load <6502Em$Dir>.SRC.mode1tab "+STR$~(code+mode1tab) 17890OSCLI"Load <6502Em$Dir>.SRC.Hmode2tab "+STR$~(code+mode2tab) 17900OSCLI"Load <6502Em$Dir>.SRC.Hmode4tab "+STR$~(code+mode4tab) 17910OSCLI"Load <6502Em$Dir>.SRC.Hmode5tab "+STR$~(code+mode5tab) 17920 17930ENDPROC 17940 17950DE 17960DEFF 17970 17980 17990DEFFNldrb2(R,S) 18000IF R<>0 OR S<>1 THEN STOP 18010IF master THEN 18020[OPTp 18030;LDRB R,[mem,S] 18040;CMP S,#&FE00 18050;BLHS ldrb_sheila 18060CMP S,#&3000 18070LDRLOB R,[mem,S] 18080BLHS ldrb_screen 18090] 18100ELSE 18110[OPTp 18120LDRB R,[mem,S] 18130;CMP S,#&FE00 18140;BLHS ldrb_sheila 18150CMP S,#&8000 18160BLHS ldrb_8000 18170] 18180ENDIF 18190="" 18200 18210DEFFNldrb16(R,S) 18220IF R<>0 OR S<>1 THEN STOP 18230IF master THEN 18240[OPTp 18250;LDRB R,[mem,S,LSR#16] 18260;CMP S,#&FE00 << 16 18270;BLHS ldrb16_sheila 18280CMP S,#&3000 << 16 18290LDRLOB R,[mem,S,LSR#16] 18300BLHS ldrb16_screen 18310] 18320ELSE 18330[OPTp 18340LDRB R,[mem,S,LSR#16] 18350;CMP S,#&FE00 << 16 18360;BLHS ldrb16_sheila 18370CMP S,#&8000 << 16 18380BLHS ldrb16_8000 18390] 18400ENDIF 18410="" 18420 18430DEFFNstrb(R,S) 18440IF R<>0 OR S<>1 THEN ERROR 18450[OPTp 18460CMP S,F,LSR#16 ; wrap_addr 18470;CMP S,#&3000 18480STRLTB R,[mem,S] 18490BLGE strb 18500] 18510="" 18520 18530DEFFNstrb16(R,S) 18540IF R<>0 OR S<>1 THEN ERROR 18550[OPTp 18560;CMP S,#&C000 << 16 18570;STRLOB R,[mem,S,LSR#16] 18580MOV S,S,LSR#16 18590CMP S,F,LSR#16 ; wrap_addr 18600;CMP S,#&3000 18610STRLTB R,[mem,S] 18620BLGE strb ; 16 18630] 18640="" 18650 18660DEFFNshowregs 18670[OPTp 18680FNprint(zpc) 18690FNprint(A) 18700FNprint(X) 18710FNprint(Y) 18720FNprint(SP) 18730FNprint(F) 18740ADD R12,mem,#&DF00 18750LDRB R12,[R12,#&DA] 18760MOV R12,R12,LSL#24 18770FNprint2(12) 18780SWI &10A 18790;SWI "OS_NewLine" 18800] 18810="" 18820 18830DEFFNprint(R) 18840CASE R OF 18850WHEN zpc : A$=FNprint4(R) 18860WHEN F : [OPTp:MOV R2,F,LSL#24:FNprint2(2):] 18870OTHERWISE 18880A$=FNprint2(R) 18890ENDCASE 18900="" 18910 18920WHEN A : A$=FNprint2(R) 18930WHEN X : A$=FNprint2(R) 18940WHEN Y : A$=FNprint2(R) 18950WHEN SP : [OPTp:SWI &100+ASC"1":FNprint2(SP):] 18960WHEN F : A$=FNprintflags 18970ENDCASE 18980="" 18990 19000DEFFNprintflags 19010[OPTp 19020TST F,#%1<<7 : SWIEQ &100+ASC"n" : SWINE &100+ASC"N" 19030TST F,#%1<<6 : SWIEQ &100+ASC"v" : SWINE &100+ASC"V" 19040TST F,#%1<<5 : SWIEQ &100+ASC"0" : SWINE &100+ASC"1" 19050TST F,#%1<<4 : SWIEQ &100+ASC"b" : SWINE &100+ASC"B" 19060TST F,#%1<<3 : SWIEQ &100+ASC"d" : SWINE &100+ASC"D" 19070TST F,#%1<<2 : SWIEQ &100+ASC"i" : SWINE &100+ASC"I" 19080TST F,#%1<<1 : SWIEQ &100+ASC"z" : SWINE &100+ASC"Z" 19090TST F,#%1<<0 : SWIEQ &100+ASC"c" : SWINE &100+ASC"C" 19100SWI &120 19110] 19120="" 19130 19140DEFFNprint2(R) 19150LOCALI% 19160[OPTp 19170MOV R1,R 19180] 19190FORI%=0 TO 1 19200[OPT p 19210MOV R1,R1,ROR#28 19220AND R0,R1,#&F 19230CMP R0,#10 19240ADDGE R0,R0,#7 19250ADD R0,R0,#48 19260SWI "OS_WriteC" 19270] 19280NEXT 19290[OPTp 19300SWI &120 19310] 19320="" 19330 19340DEFFNprint4(R) 19350LOCALI% 19360[OPTp 19370MOV R1,R 19380] 19390FORI%=0 TO 3 19400[OPT p 19410MOV R1,R1,ROR#28 19420AND R0,R1,#&F 19430CMP R0,#10 19440ADDGE R0,R0,#7 19450ADD R0,R0,#48 19460SWI "OS_WriteC" 19470] 19480NEXT 19490[OPTp 19500SWI &120 19510] 19520="" 19530 19540DEFFNprint32(R) 19550LOCALI% 19560[OPTp 19570MOV R1,R 19580] 19590FORI%=0 TO 31 19600[OPT p 19610MOV R1,R1,ROR#28 19620AND R0,R1,#&F 19630CMP R0,#10 19640ADDGE R0,R0,#7 19650ADD R0,R0,#48 19660SWI "OS_WriteC" 19670] 19680NEXT 19690[OPTp 19700SWI &120 19710] 19720="" 19730 19740DEFFNprints(A$) 19750[OPTp 19760SWI "OS_WriteS" 19770EQUS A$ 19780EQUB 10 19790EQUB 13 19800EQUB 0 19810ALIGN 19820] 19830="" 19840 19850DEFFNundoc(A%) 19860IF opcode%<>A% THEN STOP 19870[OPTp 19880;TST F,#%1000 19890;SWIEQ &100+ASC"d" 19900;SWINE &100+ASC"D" 19910 19920;SWI &100+ASC(LEFT$(RIGHT$("0"+STR$~A%,2),1)) 19930;SWI &100+ASC(RIGHT$(STR$~A%,1)) 19940;SWI &100+ASC" " 19950;FNprint(zpc) 19960;SWI &100+ASC" ":;SWI &100+ASC" " 19970 19980;MOV R0,#15 : ;SWI "OS_Byte" 19990;SWI 4 20000] 20010="" 20020 20030DEFFNequd(A%,B%) 20040LOCALI% 20050FORI%=1 TO A% 20060[OPTp 20070EQUD B% 20080] 20090NEXT 20100="" 20110 20120DEFFNdo_interrupt 20130[OPTp 20140;SWI &100+ASC"I" 20150MOV R0,zpc,LSR#24 20160FNpush(0) 20170MOV R0,zpc,LSR#16 20180FNpush(0) 20190BIC F,F,#%10000 ; clear BRK flag 20200FNpush(F) 20210ORR F,F,#%100 ; !!!!!! 20220MOV R0,#&FF00 : ADD R0,R0,#&FE 20230LDR zpc,[mem,R0] 20240MOV zpc,zpc,LSL#16 20250] 20260="" 20270 20280DEFFNdivmod(A,B,C,D,E) 20290div%+=1 20300[OPTp 20310MOV C,#1 20320MOV D,#0 20330MOV E,B 20340.divloop1(div%) 20350MOV B,B,LSL#1 20360MOV C,C,LSL#1 20370CMP B,A 20380BLO divloop1(div%) 20390 20400.divloop2(div%) 20410CMP B,A : BLS divjump(div%) 20420CMP B,E : BLS divjump(div%) 20430MOV B,B,LSR#1 20440MOV C,C,LSR#1 20450B divloop2(div%) 20460.divjump(div%) 20470CMP B,A 20480SUBLS A,A,B 20490ADDLS D,D,C 20500CMP B,E 20510BHI divloop2(div%) 20520] 20530="" 20540 20550DEFFNshadow 20560IF master THEN 20570[OPTp 20580LDRB R2,[mem,#ACCCON] 20590;EOR R2,R2,R2,LSR#2 20600TST R2,#%1 20610SUBNE R13,mem,#&13000 20620MOVEQ R13,mem 20630] 20640ELSE 20650[OPTp 20660MOV R13,mem 20670] 20680ENDIF 20690="" 20691 20700DEFPROCclearmem(S%,E%) 20710P%=buffer 20720[OPT2 20730EQUD S% ; memory 20740EQUD E% ; memory+&8000 20750.clear 20760MOV R0,#0 20770LDR R1,buffer 20780LDR R2,buffer+4 20790.loop 20800STR R0,[R1],#4 20810CMP R1,R2 20820BNE loop 20830MOV PC,R14 20840] 20850CALL clear 20860ENDPROC 20870 20880DEFFNfetch2 20890[OPTp 20900LDRB R2,[mem,zpc,LSR#16] 20910ADD PC,table,R2,LSL#8 20920] 20930="" 20940 20950DEFFNfetch3(N%,T%) 20960IF N%<>0 THEN [OPTp:ADD zpc,zpc,#N% << 16:] 20970[OPTp 20980FNshowregs2 20990SUBS time,time,#T% 21000LDRPLB R2,[mem,zpc,LSR#16] 21010ADDPL PC,table,R2,LSL#8 21020B fetch2 21030] 21040="" 21050 21060DEFFNfetch(N%,T%) 21070IF N%<>0 THEN [OPTp:ADD zpc,zpc,#N% << 16:] 21080[OPTp 21090FNshowregs2 21100SUBS time,time,#T% 21110LDRPLB R2,[mem,zpc,LSR#16] 21120ADDPL PC,table,R2,LSL#8 21130B fetch2 21140] 21150opcode%+=1 21160IF bcd_loop%=0 THEN 21170IF opcode(opcode%-1)=0 THEN STOP 21180IF opcode(opcode%)<>0 AND p=0 THEN STOP 21190IF P%-opcode(0)>opcode%*4*64 THEN PRINT~opcode% 21200P%=opcode(0)+opcode%*4*64 21210O%=code+P% 21220ELSE 21230P%=bcd(0)+opcode%*4*64 21240O%=code+P% 21250ENDIF 21260="" 21270DEFFNbcd(A%) : 21280IF P%>opcode(0)+(A%+256)*4*64 THEN STOP 21290P%=opcode(0)+(A%+256)*4*64 : O%=code+P% : ="" 21300 21310DEFFNalign16 21320WHILE (P% AND 15)<>0 21330P%+=1 : O%+=1 21340ENDWHILE 21350="" 21360DEF PROCerror 21370REPORT:PRINT " at line ";ERL 21380END 21390 21400DEFFNshowregs2 21410[OPTp 21420;BL show_regs 21430] 21440=""
� > 6502Em master=� ;*RMENSURE 6502Support 0.00 RMRun <6502Em$Res>.65Support (� � �error 2� < FIO_Podule%=� P Z9� opcode(&100), bcd(&100), code 500*1024, buffer 1000 d � l%(100) n+� divloop1(10),divloop2(10),divjump(10) x div%=0 � ț "<6502Em$Dir>.Src.Sound6" �!ț "<6502Em$Dir>.Src.Opcodes" � ț "<6502Em$Dir>.Src.Screen" � �electron%=� � �assemble � ��(end-start)/1024 �8� "Save <6502Em$Dir>.CodeE "+�~code+" "+�~(end+code) �'� "SetType <6502Em$Dir>.CodeE Data" � �� � 0�"LOAD <6502Em$Dir>.OS1,2 "+�~(memory+&C000) 2�"LOAD <6502Em$Dir>.BASICII "+�~(memory+&8000) "� 12 ,� init+code 6 �"BOO" @ J!pc_store=&D9CD << 16 T ^D%=memory : � R3 h� start+code r |� ���assemble �!�clearmem(code,code+200*1024) �R=1000 : S=1000 : T=1000 � �A=4 �X=5 �Y=6 �F=7 �SP=8 � mem=3 � time=9 � zpc=10 �table=11 a=-&100+0 x=-&100+4 & y=-&100+8 0f=-&100+12 :sp=-&100+16 Dpc_store=-&100+20 NT1mode=-&100+24 XT2mode=-&100+25 bT3mode=-&100+26 lT4mode=-&100+27 vT1=-&100+28 �T1R=-&100+32 �T2=-&100+36 �T2R=-&100+40 �T3=-&100+44 �T3R=-&100+48 �T4=-&100+52 �T4R=-&100+56 �screen=-&100+60 �screenR=-&100+64 �min=-&100+68 �sound_timer=-&100+72 �ifr=-&100+76 �ier=-&100+77 ifr2=-&100+78 ier2=-&100+79 arc_screenstart=-&100+80 tamper=-&100+84 *cursor_tamper=-&100+88 4ROMSEL_ON=-&100+92 >rom=-&100+96 HROMRAM=-&100+100 Rfe20=-&100+116 \tape_handle=-&100+117 fcrt_regs=-&100+120 pscratch=-&100+140 zpal_regs=-&100+148 �Palette=-&100+164 �ACCCON=-&100+172 �patch_on=-&100+176 �pal_tamper=-&100+177 �lastmode=-&100+178 �fe10=-&100+179 �tape_count=-&100+180 �key_addr=-&100+184 �Elatch=-&100+188 �Eifr=-&100+189 �Eier=-&100+190 �ROMint=-&100+191 �speedR=-&100+196 enD=-&100+192 (enD=-&100+200 : � don't go past this $ .�p=4 � 6 � 2 8 div%=0 BO%=code Ll%=0 VP%=0 ` opcode%=0 j [OPTp t).Oa EQUD 0 ~).Ox EQUD 0 �).Oy EQUD 0 �).Of EQUD 0 �).Osp EQUD 0 �).Opc_store EQUD 0 �,.start_offset EQUD start �(.trace EQUD 0 �(.trace2 EQUD 0 �+.init_addr EQUD init �7.crt_addr EQUD 0 ; was crt_regs �1.T1_addr EQUD 0 ; was T1 �..ifr_addr EQUD 0 ; ifr �9.column_counter_addr EQUD 0 ; column_counter 1.ROMSEL_addr EQUD 0 ; ROMSEL 2.Palette_addr EQUD 0 ; Palette 5.speed_addr EQUD screen_count+4 0.elite_addr EQUD 0 ; elite (>.opco_addr EQUD opcode(0) ; opcodetable 2-.bcd_addr EQUD bcd(0) <6.sheila_writetab_addr EQUD sheila_writetab F5.sheila_readtab_addr EQUD sheila_readtab P7.sound_vectors_addr EQUD sound_buffs_addr Z3.patch_addr EQUD patch_screen d n0.init ; only called once, before code called xADR R0,0 �;LDR R1,opco_addr �;ADD R1,R1,R0 �;LDR R2,bcd_addr �;ADD R2,R2,R0 �LDR R5,sheila_writetab_addr �ADD R5,R5,R0 �LDR R6,sheila_readtab_addr �ADD R6,R6,R0 �MOV R3,#255 �.init_loop �;LDR R4,[R1,R3,LSL#2] �;ADD R4,R4,R0 �;STR R4,[R1,R3,LSL#2] ;LDR R4,[R2,R3,LSL#2] ;ADD R4,R4,R0 ;STR R4,[R2,R3,LSL#2] "LDR R4,[R5,R3,LSL#2] ,ADD R4,R4,R0 6STR R4,[R5,R3,LSL#2] @LDR R4,[R6,R3,LSL#2] JADD R4,R4,R0 TSTR R4,[R6,R3,LSL#2] ^SUBS R3,R3,#1 hBPL init_loop rMOV PC,R14 | � .start �STMFD R13!,{R1-R12,R14} �STR R13,return_addr �STR R0,roms_addr �;LDR R0,crt_addr � ;ADR R1,0 �;ADD R0,R0,R1 �;SWI "6502_Init" � �;MOV R0,#&4000 � � � ;STR R0,[mem,#screenR] $;MOV R0,#&9C00 : ;ADD R0,R0,#&40 ;STR R0,[mem,#T1R] &; 0MOV R0,R0,LSR#2 :STR R0,[mem,#T1] DMOV R0,R0,LSR#2 NSTR R0,[mem,#screen] X b;SWI "6502_Getkeyaddr" lSWI "6502_GetElectronKeys" vSTR R0,[mem,#key_addr] � �ADR R0,block1 �ADD R1,R0,#8 �SWI "OS_ReadVduVariables" �!LDR R9,[R1] ; screenstart �!STR R9,[mem,#arc_screenstart] � MOV R9,#1 �STRB R9,[mem,#tamper] �STRB R9,[mem,#pal_tamper] � STRB R9,[mem,#cursor_tamper] � �LDR A,[mem,#a] �LDR X,[mem,#x] LDR Y,[mem,#y] "LDR SP,[mem,#sp] : �R SP,SP,#1 LDR F,[mem,#f] LDR zpc,[mem,#pc_store] * 4BL recalc_wrap >LDRB R0,[mem,#patch_on] H� R0,R0,#%111 RBIC F,F,#&FF00 \�R F,F,R0,LSL#8 f pMOV time,#0 z �LDRB R0,fe08_read �BIC R0,R0,#&81 �STRB R0,fe08_read � �ADR R0,0 �TST F,#%1000 �LDREQ table,opco_addr �LDRNE table,bcd_addr �ADD table,table,R0 �;SWI "6502_ReInit" �;SWI "6502_UpdateScreen �BL poke_updatepixelV �BL updatescreen B fetch2 .reset_bcdflag $ADR R1,0 .TST F,#%1000 8LDREQ table,opco_addr BLDRNE table,bcd_addr LADD table,table,R1 VMOV PC,R14 ` j.block1 tEQUD 149 : EQUD -1 ~.block2 �EQUD 0 : EQUD 0 � �.screen_count � EQUD 0 � EQUD 0 � � .reg_comp �EQUD &F4DF << 16 � � .trace_on �MOV R12,#1 �STRB R12,trace MOV PC,R14 .show_regs (CMP zpc,#&8000 << 16 2MOVHS PC,R14 < FLDRB R0,trace2 P CMP R0,#1 ZBEQ trace_skip d;MOVNE PC,R14 n x;LDR R0,reg_comp �;CMP R0,zpc �;SWIEQ &100+�"X" �;MOVNE PC,R14 � �SWI "6502_Checkkdata" �CMP R0,#&1F ; Insert ��Q R1,#1 �STREQ R1,trace2 � �MOV PC,R14 � ��Q R0,#1 �STREQB R0,trace LDRB R0,trace CMP R0,#1 "MOVNE PC,14 , 6.trace_skip @ �showregs JMOV PC,R14 T ^ h r.keychk | EQUD 0 � �.fetch2 � �LDR R0,[mem,#min] �SUB R0,R0,time �LDR R1,[mem,#sound_timer] �SUB R1,R1,R0 �STR R1,[mem,#sound_timer] � � �MOV R0,#0 : STR R0,keychk �LDR R0,[mem,#min] �SUB R0,R0,time ; *** LDR R1,[mem,#screen] SUBS R1,R1,R0 STRGT R1,[mem,#screen] &BLLE vsync 0 :LDR R0,[mem,#min] DSUB R0,R0,time ; *** NLDR R1,speed XSUBS R1,R1,R0 bSTRGT R1,speed lBLLE speed_control v �; LDR R0,[mem,#T1mode] �; TST R0,#%1 �; BEQ skip_timer1 � �LDR R0,[mem,#min] �SUB R0,R0,time ; *** �LDR R1,[mem,#T1] �SUBS R1,R1,R0 �STRGT R1,[mem,#T1] �BLLE timer1 �.skip_timer1 � �LDR R0,[mem,#min] SUB R0,R0,time LDR R1,[mem,#tape_count] SUBS R1,R1,R0 STRGT R1,[mem,#tape_count] *BLLE tape_fetch 4 > HTST F,#%100 RBNE skip_do_interrupt \ f;.do_interrupt p zLDRB R1,[mem,#Eifr] �;TST R1,#%1000000 �;SWINE &100+�"6" �� R1,R1,#%01111100 � � �*;� R1,R1,#%01110000 ; ???????????????? � � � �LDRB R2,[mem,#Eier] � ��S R1,R1,R2 � ;TST R1,#%1000000 ;SWINE &100+�"6" ;TST R1,#%100000 $;SWINE &100+�"5" .;TST R1,#%10000 8;SWINE &100+�"4" B;TST R1,#%1000 L V;SWINE &100+�"3" `;TST R1,#%100 j;SWINE &100+�"2" t;CMP R1,#0 ~ �BEQ skip_do_interrupt � �.do_interrupt ��do_interrupt � �.skip_do_interrupt � �;BL keyboard �D � CLI!!! �BL keys2 �.skip_keys �LDR time,[mem,#T1] �;MOV time,time,LSR#15 LDR R1,[mem,#screen] CMP R1,#0 : �Q R1,time CMP R1,time MOVLT time,R1 ( 2LDR R1,[mem,#tape_count] <CMP R1,time FMOVLT time,R1 P ZCMP time,#0 : �Q time,#1 dSTR time,[mem,#min] n�fetch2 x �.interrupt ; called by CLI �MOV PC,R14 � �LDRB R1,[mem,#Eifr] �;� R1,R1,#%00110000 �LDRB R2,[mem,#Eier] � ��S R1,R1,R2 � �Q PC,R14 � �;TST R1,#%100000 �;SWINE &100+�"5" �;TST R1,#%1000000 ;SWINE &100+�"6" �do_interrupt " ,MOV PC,R14 6 @.F10temp J EQUD 0 T ^.F10 hSWI "6502_Getkdata" rSTR R14,F10temp |MOV R0,#255 �STRB R0,[mem,#lastmode] �BL updatescreen �;BL force_update_pal �LDR PC,F10temp � �;.fetch3 � .keys2 �SWI "6502_Checkkdata" �CMP R0,#&1F ; Insert ��Q R1,#1 �STREQ R1,trace2 �CMP R0,#10 ; F10 �BEQ F10 CMP R0,#11 ; F11 CMPNE R0,#12 ; F12 CMPNE R0,#15 ; break &BEQ raw_exit2 0MOV PC,R14 : D.keyboard ; called by CLI N XMOV R0,#1 : STR R0,keychk bSWI "6502_Getkdata" lCMP R0,#&FF : �Q PC,R14 vCMP R0,#&1F ; Insert ��Q R1,#1 �STREQ R1,trace2 �CMP R0,#10 ; F10 �BEQ F10 �CMP R0,#15 �CMPNE R0,#12 �CMPNE R0,#11 ; F11 �BEQ raw_exit � �;CMP R0,#0 ; escape �;LDREQB R0,[mem,#&FF] �;�REQ R0,R0,#&80 �;STREQB R0,[mem,#&FF] LDRB R0,[R1,R0] CMP R0,#&FF ;BEQ not_keyboard �Q PC,R14 * 4;B not_keyboard >CMP R0,#10 ; shift, ctrl HMOVLT PC,R14 RLDRB R1,[mem,#ifr] \-�R R1,R1,#%1 ; interrupt is from keyboard fSTRB R1,[mem,#ifr] pLDRB R0,[mem,#ier] zTST R0,#%1 � �Q PC,R14 ��do_interrupt �MOV PC,R14 � � � �.mono_time � EQUD 0 � .speed � EQUD 0 � �.speed_control �LDR R0,[mem,#speedR] ADD R1,R1,R0 STR R1,speed $LDR R1,mono_time ..mono_loop 8SWI "OS_ReadMonotonicTime" BMOV R0,R0,LSR#1 L CMP R0,R1 VBEQ mono_loop `STR R0,mono_time j tMOV PC,R14 ~ � .vsync �STR R14,vsyncR14 �;MOV R0,#19 �;SWI "OS_Byte" � �;LDRB R0,ldrb40_tamper �$;CMP R0,#1 : ;BLEQ ldrb40_update � � �"LDR R0,[mem,#speedR] ; screenR �ADD R1,R1,R0 �STR R1,[mem,#screen] ;BL trace_on (;LDRB R1,screen_count 2;SUBS R1,R1,#1 <;LDRMIB R1,screen_count+4 F;STRB R1,screen_count PLDR R0,[mem,#tamper] Z CMP R0,#0 d nBEQ no_tamper x MOV R0,#0 �STR R0,[mem,#tamper] �;SWI "6502_UpdateScreen" �BL recalc_wrap �BL updatescreen �TST F,#1 << 10 ; cursor on? �;BLNE define_cursor �;BLNE cursor �.no_tamper �LDRB R0,[mem,#pal_tamper] � CMP R0,#0 �BLNE update_pal � � LDR R0,[mem,#cursor_tamper] CMP R0,#0 ;BLNE cursor " , 6;SUB R0,mem,#512 ; sheila @;LDRB R1,[R0,#&20] J;TST R1,#%10 ; teletext? T;SWINE "6502_UpdateScreen" ^;BLNE updatescreen h;ADD R0,R0,#&4D r;LDRB R1,[R0] |;LDRB R2,[R0,#1] � � � �LDRB R1,[mem,#Eifr] �,�R R1,R1,#%100 ; interrupt is from vsync �STRB R1,[mem,#Eifr] � �;TST F,#1 << 9 �;BEQ skip_exact � �;LDR R1,mono_time �;.mono_loop �;SWI "OS_ReadMonotonicTime" ;MOV R0,R0,LSR#1 ;CMP R0,R1 ;BEQ mono_loop &;STR R0,mono_time 0 :.skip_exact D NLDR PC,vsyncR14 X .vsyncR14 b EQUD 0 l v � �.timer1 �"LDR R0,[mem,#speedR] ; was T1R �ADD R1,R1,R0 �STR R1,[mem,#T1] � �LDRB R1,[mem,#Eifr] �+�R R1,R1,#%1000 ; interrupt is from RTC �STRB R1,[mem,#Eifr] � �MOV PC,R14 � � ;.trace2 ;EQUD 0 * .reset 4;MOV R1,#1 >;STR R1,trace H*MOV R0,#15 : MOV R1,#0 : SWI "OS_Byte" RMOV R0,#&10000 \SUB R0,R0,#4 fLDR R0,[mem,R0] pMOV zpc,R0,LSL#16 z'BIC F,F,#%1000 ; clear Decimal mode �)�R F,F,#%100 ; set interrupt disable ��fetch2 � � � .exit � MOV R0,#0 �.raw_exit2 �SWI "6502_Getkdata" � .raw_exit �STR A,[mem,#a] �STR X,[mem,#x] �STR Y,[mem,#y] �STR SP,[mem,#sp] STR F,[mem,#f] STR zpc,[mem,#pc_store] LDR R13,return_addr $LDMFD R13!,{R1-R12,PC} .;MOV PC,R14 8 B.return_addr L EQUD 0 V `.roms_addr j EQUD 0 t ~ �.fe08_read �.casette_read � EQUB 0 �.fe08_write � EQUB 0 � .fe09 � EQUB 0 � ;.fe10 �;EQUB 0 � ALIGN �.tbuffer � EQUD 0 .read_tape_data LDRB R0,[mem,#Eifr] BIC R0,R0,#%10000 ( 2STRB R0,[mem,#Eifr] <LDRB R0,fe09 F;CMP R0,#�"*" P;SWIEQ &100+�"h" Z;SWINE &100+�"H" d;MOV R0,#�"*" n xMOV PC,R14 � �.tape_fetch �;SWI &100+�"b" �;LDR R0,[mem,#tapeR] �0;MOV R0,#&3400 ; 2000000/(1200/8)~=1200 baud �MOV R0,#&6000 �ADDS R1,R1,R0 �MOVLE R1,#&6000 � �LDR R0,[mem,#Elatch] �&TST R0,#%110 ; casette input mode? �MOVNE R1,#&100000 � $TST R0,#%1000000 ; is *Motor on? �Q R1,#&100000 "STR R1,[mem,#tape_count] , 6 �Q PC,R14 @ JLDRB R1,[mem,#tape_handle] T CMP R1,#0 ^ �Q PC,R14 h r .tape_get |;SWI &100+�"B" �SWI "XOS_BGet" �MOVVS R1,#0 � STRVSB R1,[mem,#tape_handle] �MOVVS PC,R14 � �BCC tape_skip10 � � MOV R0,#1 � MOV R2,#0 �)SWI "XOS_Args" ; rewind tape to start �MOVVS R1,#0 � STRVSB R1,[mem,#tape_handle] �MOVVS PC,R14 .tape_skip10 ;CMP R0,#�"*" &;SWIEQ &100+�"*" 0 :CMP R0,#&FF DBNE not_FF NSWIEQ "XOS_BGet" XCMP R0,#&FF bBEQ not_FF l v;MOV R0,R0,LSL#4 � �;LDRB R1,fe08_read �LDRB R1,[mem,#Eifr] � �TST R0,#%100 �BICEQ R1,R1,#%1000000 ��RNE R1,R1,#%1000000 � �STRB R1,[mem,#Eifr] � � �Q PC,R14 � �LDRB R0,[mem,#ier] TST R0,#%1000000 �Q PC,R14 ;�R R1,R1,#&80 *;STRB R1,fe08_read 4;SWI &100+�"F" >B do_interrupt H;B interrupt R;B skip_do_interrupt \ f.not_FF pSTRB R0,fe09 z �;SWI &100+�"B" � �;LDRB R0,fe08_write �/;TST R0,#&80 ; receive interrupt enable bit �;�Q PC,R14 � �;LDRB R0,fe08_read �;�R R0,R0,#&81 �;STRB R0,fe08_read �LDRB R0,[mem,#Eifr] ��R R0,R0,#%10000 �STRB R0,[mem,#Eifr] � ;LDRB R12,[mem,#&C2] ;MOV R12,R12,LSL#24 ;�print2(12) $;SWI &100+�" " . 8LDRB R0,[mem,#Eier] B1TST R0,#%10000 ; receive interrupt enable bit L;SWIEQ &100+�"Q" V;�Q PC,R14 `;SWI &100+�"i" jB do_interrupt t;B interrupt ~;MOV PC,R14 � � .dummy �MOV PC,R14 � � �&.strb8000 ; greater than 8000 �] �� master � � [OPTp �CMP R1,#&E000 �BGE strb_rom_ret �CMP R1,#&C000 BGE strb_rom_ret2 CMP R1,#&9000 BGE strb_rom ] (� 2 [OPTp <CMP R1,#&C000 FBGE strb_rom_ret P] Z� d [OPTp n xLDRB R12,[mem,#rom] �TST R12,#&80 �BEQ strb_rom � �0;SUB R13,mem,#(&8000+&B000) ; 4k Private RAM �;STRB R0,[R13,R1] �STRB R0,[mem,R1] �MOV PC,R14 � � .strb_rom �SUB R12,mem,#-ROMRAM �LDRB R13,[mem,#rom] �LDRB R13,[R12,R13] �CMP R13,#0 STREQB R0,[mem,R1] MOV PC,R14 ;B strb_rom_ret " ,.romsel 6LDRB R12,[mem,#ROMSEL_ON] @CMP R12,#0 JMOVNE PC,R14 T ^LDRB R1,[mem,#rom] h rLDR R12,roms_addr |� R2,R0,#&F ; socket number �LDRB R1,[mem,#rom] �CMP R2,R1:�Q PC,R14 �� R1,R1,#&F �� R0,R0,#&F �STRB R0,[mem,#rom] �SUB R13,mem,#-ROMRAM �LDRB R13,[R13,R1] �1CMP R13,#0 ; is the bank being paged out RAM? �BNE romsel2 � �.TST R0,#%10000000 ; private RAM mapped in? ��Q R13,#&8000 �MOVNE R13,#&9000 � R0,R0,#&F ADD R2,R12,R1,LSL#14 &ADDNE R2,R2,#&1000 0&ADD R12,R12,R0,LSL#14 ; R0*16*1024 :ADDNE R12,R12,#&1000 DADR R1,romsel_loop_temp NSTMIA R1,{R0,R4-R8,R14} XADD mem,mem,R13 bRSB R13,R13,#&C000 l.romsel_loop v(LDMIA mem,{R0,R1,R4,R5,R6,R7,R8,R14} �(STMIA R2!,{R0,R1,R4,R5,R6,R7,R8,R14} �)LDMIA R12!,{R0,R1,R4,R5,R6,R7,R8,R14} �+STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R14} �SUBS R13,R13,#4*8 �BNE romsel_loop �SUB mem,mem,#&C000 �ADR R1,romsel_loop_temp �LDMIA R1,{R0,R4-R8,PC} �.romsel_loop_temp �EQUD 0:EQUD 0:EQUD 0:EQUD 0 �EQUD 0:EQUD 0:EQUD 0:EQUD 0 � �.romsel_empty !ADD R13,R2,R2,LSL#8 !ADD R13,R13,R13,LSL#16 !ADD R0,mem,#&8000 ! STR R13,[R0,#0] !*STR R13,[R0,#4] !4STR R13,[R0,#8] !>STR R13,[R0,#12] !HMOV PC,R14 !R !\.romsel2 !f !pSUB R13,mem,#-ROMRAM !zLDRB R13,[R13,R2] !�3CMP R13,#2 ; is the bank being paged out empty? !�BEQ romsel_empty !� !�.TST R0,#%10000000 ; private RAM mapped in? !��Q R13,#&8000 !�MOVNE R13,#&9000 !�� R0,R0,#&F !� !� !�&ADD R12,R12,R0,LSL#14 ; R0*16*1024 !�ADDNE R12,R12,#&1000 !�ADD mem,mem,R13 !�RSB R13,R13,#&C000 "ADR R1,romsel_loop_temp "STMIA R1,{R0,R4-R8,R14} ".romsel2_loop "$+LDMIA R12 !,{R0,R1,R4,R5,R6,R7,R8,R14} ".+STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R14} "8;LDR R1,[R12],#4 "B=;STR R1,[mem],#4 ; store byte from ROM in main memory map "LSUBS R13,R13,#4*8 "VBNE romsel2_loop "`SUB mem,mem,#&C000 "jADR R1,romsel_loop_temp "tLDMIA R1,{R0,R4-R8,PC} "~ "� .link "� EQUD 0 "� "��screen "� "�.write_palette "�� R1,R1,#7 "�SUB R12,mem,#-pal_regs "�LDRB R2,[R12,R1] "�CMP R0,R2:�Q PC,R14 "�STRB R0,[R12,R1] "� # LDR R1,[mem,#Palette] # CMP R1,#0 #MOVNE PC,R14 # #()MOV R1,#255:STRB R1,[mem,#pal_tamper] #2MOV PC,R14 #< #F.update_pal #PLDR R1,[mem,#Palette] #Z CMP R1,#0 #dMOVNE PC,R14 #n.force_update_pal #xLDRB R1,[mem,#fe20] #�;TST R1,#%10 #�;MOVNE PC,R14 ; mode 7 #�� R1,R1,#%11100 #�"CMP R1,#%11100 : BEQ twocolpal #�"CMP R1,#%01000 : BEQ twocolpal #�#CMP R1,#%11000 : BEQ fourcolpal #�#CMP R1,#%00100 : BEQ fourcolpal #� #� #�.sixteencolpal #�LDRB R1,[mem,#pal_regs+0] #�LDRB R2,[mem,#pal_regs+1] #� $ MOV R0,#0 $TST R2,#%1 ; r0 $�REQ R0,R0,#%1 $"TST R2,#%10000 ; g0 $,�REQ R0,R0,#%10 $6TST R1,#%10000 ; b0 $@�REQ R0,R0,#%100 $J $TSWI &100+19 $^SWI &100+0 $hSWI "OS_WriteC" $rSWI &100 $|SWI &100 $�SWI &100 $� $� MOV R0,#0 $�TST R2,#%10 ; r2 $��REQ R0,R0,#%1 $�TST R2,#%100000 ; g2 $��REQ R0,R0,#%10 $�TST R1,#%100000 ; b2 $��REQ R0,R0,#%100 $� $�SWI &100+19 $�SWI &100+2 $�SWI "OS_WriteC" %SWI &100 %SWI &100 %SWI &100 %& %0 MOV R0,#0 %:TST R2,#%100 ; r8 %D�REQ R0,R0,#%1 %NTST R1,#%100 ; g8 %X�REQ R0,R0,#%10 %bTST R1,#%1000000 ; b8 %l�REQ R0,R0,#%100 %v %�SWI &100+19 %�SWI &100+8 %�SWI "OS_WriteC" %�SWI &100 %�SWI &100 %�SWI &100 %� %� MOV R0,#0 %�TST R2,#%1000 ; r10 %��REQ R0,R0,#%1 %�TST R1,#%1000 ; g10 %��REQ R0,R0,#%10 %�TST R1,#%10000000 ; b10 &�REQ R0,R0,#%100 & &SWI &100+19 & SWI &100+10 &*SWI "OS_WriteC" &4SWI &100 &>SWI &100 &HSWI &100 &R &\LDRB R1,[mem,#pal_regs+2] &fLDRB R2,[mem,#pal_regs+3] &p &z MOV R0,#0 &�TST R2,#%1 ; r4 &��REQ R0,R0,#%1 &�TST R2,#%10000 ; g4 &��REQ R0,R0,#%10 &�TST R1,#%10000 ; b4 &��REQ R0,R0,#%100 &� &�SWI &100+19 &�SWI &100+4 &�SWI "OS_WriteC" &�SWI &100 &�SWI &100 &�SWI &100 ' ' MOV R0,#0 'TST R2,#%10 ; r6 '$�REQ R0,R0,#%1 '.TST R2,#%100000 ; g6 '8�REQ R0,R0,#%10 'BTST R1,#%100000 ; b6 'L�REQ R0,R0,#%100 'V '`SWI &100+19 'jSWI &100+6 'tSWI "OS_WriteC" '~SWI &100 '�SWI &100 '�SWI &100 '� '� MOV R0,#0 '�TST R2,#%100 ; r12 '��REQ R0,R0,#%1 '�TST R1,#%100 ; g12 '��REQ R0,R0,#%10 '�TST R1,#%1000000 ; b12 '��REQ R0,R0,#%100 '� '�SWI &100+19 ( SWI &100+12 ( SWI "OS_WriteC" (SWI &100 (SWI &100 ((SWI &100 (2 (< MOV R0,#0 (FTST R2,#%1000 ; r14 (P�REQ R0,R0,#%1 (ZTST R1,#%1000 ; g14 (d�REQ R0,R0,#%10 (nTST R1,#%10000000 ; b14 (x�REQ R0,R0,#%100 (� (�SWI &100+19 (�SWI &100+14 (�SWI "OS_WriteC" (�SWI &100 (�SWI &100 (�SWI &100 (� (�LDRB R1,[mem,#pal_regs+4] (�LDRB R2,[mem,#pal_regs+5] (� (� MOV R0,#0 (�TST R2,#%1 ; r5 )�REQ R0,R0,#%1 )TST R2,#%10000 ; g5 )�REQ R0,R0,#%10 )"TST R1,#%10000 ; b5 ),�REQ R0,R0,#%100 )6 )@SWI &100+19 )JSWI &100+5 )TSWI "OS_WriteC" )^SWI &100 )hSWI &100 )rSWI &100 )| )� MOV R0,#0 )�TST R2,#%10 ; r7 )��REQ R0,R0,#%1 )�TST R2,#%100000 ; g7 )��REQ R0,R0,#%10 )�TST R1,#%100000 ; b7 )��REQ R0,R0,#%100 )� )�SWI &100+19 )�SWI &100+7 )�SWI "OS_WriteC" )�SWI &100 )�SWI &100 *SWI &100 * * MOV R0,#0 *&TST R2,#%100 ; r13 *0�REQ R0,R0,#%1 *:TST R1,#%100 ; g13 *D�REQ R0,R0,#%10 *NTST R1,#%1000000 ; b13 *X�REQ R0,R0,#%100 *b *lSWI &100+19 *vSWI &100+13 *�SWI "OS_WriteC" *�SWI &100 *�SWI &100 *�SWI &100 *� *� MOV R0,#0 *�TST R2,#%1000 ; r15 *��REQ R0,R0,#%1 *�TST R1,#%1000 ; g15 *��REQ R0,R0,#%10 *�TST R1,#%10000000 ; b15 *��REQ R0,R0,#%100 *� +SWI &100+19 +SWI &100+15 +SWI "OS_WriteC" + SWI &100 +*SWI &100 +4SWI &100 +> +HLDRB R1,[mem,#pal_regs+6] +RLDRB R2,[mem,#pal_regs+7] +\ +f MOV R0,#0 +pTST R2,#%1 ; r1 +z�REQ R0,R0,#%1 +�TST R2,#%10000 ; g1 +��REQ R0,R0,#%10 +�TST R1,#%10000 ; b1 +��REQ R0,R0,#%100 +� +�SWI &100+19 +�SWI &100+1 +�SWI "OS_WriteC" +�SWI &100 +�SWI &100 +�SWI &100 +� +� MOV R0,#0 ,TST R2,#%10 ; r3 ,�REQ R0,R0,#%1 ,TST R2,#%100000 ; g3 ,$�REQ R0,R0,#%10 ,.TST R1,#%100000 ; b3 ,8�REQ R0,R0,#%100 ,B ,LSWI &100+19 ,VSWI &100+3 ,`SWI "OS_WriteC" ,jSWI &100 ,tSWI &100 ,~SWI &100 ,� ,� MOV R0,#0 ,�TST R2,#%100 ; r9 ,��REQ R0,R0,#%1 ,�TST R1,#%100 ; g9 ,��REQ R0,R0,#%10 ,�TST R1,#%1000000 ; b9 ,��REQ R0,R0,#%100 ,� ,�SWI &100+19 ,�SWI &100+9 ,�SWI "OS_WriteC" - SWI &100 - SWI &100 -SWI &100 - -( MOV R0,#0 -2TST R2,#%1000 ; r11 -<�REQ R0,R0,#%1 -FTST R1,#%1000 ; g11 -P�REQ R0,R0,#%10 -ZTST R1,#%10000000 ; b11 -d�REQ R0,R0,#%100 -n -xSWI &100+19 -�SWI &100+11 -�SWI "OS_WriteC" -�SWI &100 -�SWI &100 -�SWI &100 -� -�MOV PC,R14 -� -�.twocolpal -�LDRB R1,[mem,#pal_regs+0] -�LDRB R2,[mem,#pal_regs+1] -� MOV R0,#0 -�TST R2,#%1 ; r0 .�REQ R0,R0,#%1 .TST R2,#%10000 ; g0 .�REQ R0,R0,#%10 ."TST R1,#%10000 ; b0 .,�REQ R0,R0,#%100 .6 .@SWI &100+19 .JSWI &100+0 .TSWI "OS_WriteC" .^SWI &100 .hSWI &100 .rSWI &100 .| .� MOV R0,#0 .�TST R2,#%100 ; r1 .��REQ R0,R0,#%1 .�TST R1,#%100 ; g1 .��REQ R0,R0,#%10 .�TST R1,#%1000000 ; b1 .��REQ R0,R0,#%100 .� .�SWI &100+19 .�SWI &100+3 ; mode 4 fix .�SWI "OS_WriteC" .�SWI &100 .�SWI &100 /SWI &100 /MOV PC,R14 / /&.fourcolpal /0LDRB R1,[mem,#pal_regs+0] /:LDRB R2,[mem,#pal_regs+1] /D MOV R0,#0 /NTST R2,#%1 ; r0 /X�REQ R0,R0,#%1 /bTST R2,#%10000 ; g0 /l�REQ R0,R0,#%10 /vTST R1,#%10000 ; b0 /��REQ R0,R0,#%100 /� /�SWI &100+19 /�SWI &100+0 /�SWI "OS_WriteC" /�SWI &100 /�SWI &100 /�SWI &100 /� /� MOV R0,#0 /�TST R2,#%10 ; r1 /��REQ R0,R0,#%1 /�TST R2,#%100000 ; g1 0�REQ R0,R0,#%10 0TST R1,#%100000 ; b1 0�REQ R0,R0,#%100 0 0*SWI &100+19 04SWI &100+1 0>SWI "OS_WriteC" 0HSWI &100 0RSWI &100 0\SWI &100 0f 0p MOV R0,#0 0zTST R2,#%100 ; r2 0��REQ R0,R0,#%1 0�TST R1,#%100 ; g2 0��REQ R0,R0,#%10 0�TST R1,#%1000000 ; b2 0��REQ R0,R0,#%100 0� 0�SWI &100+19 0�SWI &100+2 0�SWI "OS_WriteC" 0�SWI &100 0�SWI &100 0�SWI &100 0� 1 MOV R0,#0 1TST R2,#%1000 ; r3 1�REQ R0,R0,#%1 1$TST R1,#%1000 ; g3 1.�REQ R0,R0,#%10 18TST R1,#%10000000 ; b3 1B�REQ R0,R0,#%100 1L 1VSWI &100+19 1`SWI &100+3 1jSWI "OS_WriteC" 1tSWI &100 1~SWI &100 1�SWI &100 1� 1�MOV PC,R14 1� 1�.write_screen_start_low 1�� R0,R0,#%11100000 1�STRB R0,[mem,#crt_regs+13] 1�%MOV R0,#1 : STRB R0,[mem,#tamper] 1�MOV PC,R14 1� 1�.read_screen_start_low 1�LDRB R0,[mem,#crt_regs+13] 2 MOV PC,R14 2 2.write_screen_start_high 2� R0,R0,#%00111111 2(STRB R0,[mem,#crt_regs+12] 22%MOV R0,#1 : STRB R0,[mem,#tamper] 2<MOV PC,R14 2F 2P.read_screen_start_high 2ZLDRB R0,[mem,#crt_regs+12] 2dMOV PC,R14 2n 2x.write_iscr ; &FE00 2� 2�LDRB R1,[mem,#Eier] 2� 2�TST R0,#&80 2��REQ R1,R1,R0 2�BICNE R1,R1,R0 2�� R1,R1,#%01111100 2�STRB R1,[mem,#Eier] 2�MOV PC,R14 2� 2� 2� 2�TST R0,#&80 3;SWIEQ &100+�"[" 3;SWINE &100+�"]" 3� R0,R0,#%01111100 3"STRB R0,[mem,#Eier] 3,;SWI &100+�"[" 36;MOV R12,R0,LSL#24 3@;�print2(12) 3JMOV PC,R14 3T 3^.read_iscr ; &FE00 3hLDRB R0,[mem,#Eifr] 3rBIC R1,R0,#%10 3|STRB R1,[mem,#Eifr] 3� 3�;LDRB R1,[mem,#Eier] 3�;�S R1,R1,R0 3�BICS R1,R0,#%11 3�#�RNE R0,R0,#%1 ; master IRQ bit 3� 3�;BIC R0,R0,#%1000000 3�;LDRB R1,[mem,#&C2] 3�;CMP R1,#1 3�;�REQ R0,R0,#%1000000 3�;CMP R1,#2 3�;BICEQ R0,R0,#%1000000 3�;�REQ R0,R0,#%1000000 4 4MOV PC,R14 4 4&.recalc_wrap 40LDRB R0,[mem,#Elatch] 4:$� R0,R0,#%00111000 ; screen mode 4DMOV R0,R0,LSR#1 4NADR R1,mode_table 4XLDR R0,[R1,R0] 4b 4lBIC F,F,#&FF000000 4vBIC F,F,#&00FF0000 4� �R F,F,R0,LSL#16 ; wrap_addr 4� 4�MOV PC,R14 4� 4�.counter_last 4� EQUD 0 4� 4�.write_counter 4�LDRB R1,R14store+4 4�CMP R0,R1:�Q PC,R14 4� 4�STR R14,R14store 4�ADD R0,R0,#1 5STRB R0,R14store+4 5 5LDR R0,[mem,#min] 5 SUB R0,R0,time 5*LDR R1,[mem,#sound_timer] 54SUB R1,R1,R0 5>LDR R2,counter_last 5HSTR R1,counter_last 5RSUB R1,R2,R1 5\CMP R1,#200 5f;SWILT &100+�"s" 5pBGE skip_noise 5z 5�+MOV R0,#%11100100 ; low frequency noise 5�STRB R0,sound_data 5�MOV R0,#0 : BL sound_latch 5�,MOV R0,#%11110000 ; maximum volume noise 5�STRB R0,sound_data 5�MOV R0,#0 : BL sound_latch 5�*MOV R0,#%11011111 ; channel 1 volume 0 5�STRB R0,sound_data 5�MOV R0,#0 : BL sound_latch 5� 5�LDR PC,R14store 5�;B skip_noise2 5� 6.skip_noise 6&MOV R0,#%11111111 ; noise volume 0 6STRB R0,sound_data 6$MOV R0,#0 : BL sound_latch 6. 68.skip_noise2 6BLDRB R0,R14store+4 6L 6VMOV R0,R0,LSL#2 6`� R0,R0,#%1111 6j%�R R0,R0,#%11000000 ; tone 1 freq 6tSTRB R0,sound_data 6~ MOV R0,#0 6�BL sound_latch 6�LDRB R0,R14store+4 6�MOV R0,R0,LSR#2 6�STRB R0,sound_data 6�LDR R14,R14store 6� MOV R0,#0 6�B sound_latch 6� 6� .R14store 6� EQUD 0 6� EQUD 0 6� 7 .write_latch 7 STRB R0,[mem,#Elatch] 7 7STR R14,R14store 7(TST R0,#%10 72)�Q R0,#%11011111 ; channel 1 volume 0 7<-MOVNE R0,#%11010000 ; channel 1 volume 15 7FSTRB R0,sound_data 7P MOV R0,#0 7ZBL sound_latch 7d 7n&MOV R0,#%11111111 ; noise volume 0 7xSTRB R0,sound_data 7�MOV R0,#0 : BL sound_latch 7� 7�LDR R14,R14store 7�LDRB R0,[mem,#Elatch] 7� 7�$� R0,R0,#%00111000 ; screen mode 7�LDRB R1,mode 7� CMP R0,R1 7� �Q PC,R14 7�STRB R0,mode 7� 7�%MOV R1,#1 : STRB R1,[mem,#tamper] 7� 8CMP R0,#7 << 3 8�REQ F,F,#1 << 12 8BICNE F,F,#1 << 12 8"SWIEQ &100+12 8, 86CMP R0,#3 << 3 8@MOVLE R1,#80 8JMOVGT R1,#40 8T5STRB R1,[mem,#crt_regs+1] ; horizontal characters 8^MOV R0,R0,LSR#1 8hADR R1,mode_table 8rLDR R0,[R1,R0] 8| 8�BIC F,F,#&FF000000 8�BIC F,F,#&00FF0000 8� �R F,F,R0,LSL#16 ; wrap_addr 8� 8�MOV R0,R0,LSR#16 8�� R1,R0,#&FF 8�3STRB R1,[mem,#crt_regs+6] ; vertical characters 8�MOV R1,#&24 8�%STRB R1,[mem,#crt_regs+3] ; misc. 8�MOV R0,R0,LSR#8 8�STRB R0,[mem,#fe20] 8�-B poke_updatepixelV ; includes MOV PC,R14 8� 9 .mode 9 EQUD 0 9 9&.mode_table 90EQUD &9C203000 ; mode 0 9:EQUD &D8203000 ; mode 1 9DEQUD &F4203000 ; mode 2 9NEQUD &9C194000 ; mode 3 9XEQUD &88205800 ; mode 4 9bEQUD &C4205800 ; mode 5 9lEQUD &88196000 ; mode 6 9vEQUD &88196000 ; (mode 7) 9� 9�.read_latch 9�LDRB R0,[mem,#Elatch] 9�MOV PC,R14 9� 9�.write_ROMint 9�STRB R0,[mem,#ROMint] 9�LDRB R1,[mem,#Eifr] 9�TST R0,#%10000 9�BICNE R1,R1,#%100 9�;SWINE &100+�"/" 9�TST R0,#%100000 9�BICNE R1,R1,#%1000 :;SWINE &100+�"." :TST R0,#%1000000 :9BICNE R1,R1,#%1000000 ; clear (some?) tape interrupts : ;SWINE &100+�"," :*STRB R1,[mem,#Eifr] :4� R0,R0,#%1111 :> CMP R0,#8 :HCMPNE R0,#9 :R�REQ F,F,#1 << 11 :\BICNE F,F,#1 << 11 :f;SWIEQ &100+�"1" :p;SWINE &100+�"0" :zBNE romsel :�MOV PC,R14 :� :�.read_ROMint :�.read_counter :�.write_tape_data :�.read_palette :�MOV PC,R14 :� :��sound_latch :��sound_misc :� :�.osbput :�MOV R0,A,LSR#24 ;MOV R1,Y,LSR#24 ;SWI "XOS_BPut" ;BVS swi_error ;$B opcode(&60) ; rts ;. ;8.osbget ;BMOV R0,A,LSR#24 ;LMOV R1,Y,LSR#24 ;VSWI "XOS_BGet" ;`BVS swi_error ;jMOV A,R0,LSL#24 ;t�setupC ;~B opcode(&60) ; rts ;� ;�.swi_error ;�ADD mem,mem,#&100 ;�ADD mem,mem,#&002 ;�MOV R1,#0 ; BRK ;�STRB R1,[mem,#-2] ;�LDRB R1,[R0] ; error no ;�STRB R1,[mem,#-1] ;�ADD R0,R0,#4 ;�MOV R14,#0 ;� ;�.swi_err_loop <