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
<