Home » Archimedes archive » Zipped Apps » 6502em » !6502Em/src/6502Em130M
!6502Em/src/6502Em130M
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/6502Em130M |
| Read OK: | ✔ |
| File size: | ED7E bytes |
| Load address: | 0000 |
| Exec address: | 0000 |
File contents
10REM > 6502Em
20REMINPUT"Hardware scroll ";HWScroll
30REMIF HWScroll<>0 THEN HWScroll=TRUE
40HWScroll=TRUE
50master=FALSE
60*RMENSURE 6502Support 0.00 RMRun <6502Em$Res>.65Support
70ON ERROR PROCerror
80
90REM V2. (master)
100
110pagetable=&97000
120
130IO_Podule%=FALSE
140
150DIM opcode(&100), bcd(&100), code 500*1024, buffer 1000
160DIM l%(100)
170DIM divloop1(10),divloop2(10),divjump(10)
180div%=0
190LIBRARY "<6502Em$Dir>.Src.Sound6"
200LIBRARY "<6502Em$Dir>.Src.OpcodesNew"
210LIBRARY "<6502Em$Dir>.Src.ScreenNew"
220LIBRARY "<6502Em$Dir>.Src.HWScroll"
230
240electron%=FALSE
250master=FALSE
260REMPROCassemble
270
280REMPRINT(end-start)/1024
290REMOSCLI "Save <6502Em$Dir>.Code "+STR$~code+" "+STR$~(end+code)
300REMOSCLI "SetType <6502Em$Dir>.Code Data"
310
320master=TRUE
330PROCassemble
340PRINT(end-start)/1024
350OSCLI "Save <6502Em$Dir>.CodeM "+STR$~code+" "+STR$~(end+code)
360OSCLI "SetType <6502Em$Dir>.CodeM Data"
370
380END
390
400OSCLI"LOAD <6502Em$Dir>.OS1,2 "+STR$~(memory+&C000)
410OSCLI"LOAD <6502Em$Dir>.BASICII "+STR$~(memory+&8000)
420
430MODE 12
440CALL init+code
450PRINT"BOO"
460
470!pc_store=&D9CD << 16
480
490D%=memory : REM R3
500CALL start+code
510
520END
530DEFPROCassemble
540PROCclearmem(code,code+200*1024)
550R=1000 : S=1000 : T=1000
560
570A=4
580X=5
590Y=6
600F=7
610SP=8
620mem=3
630time=9
640zpc=10
650table=11
660
670a=-&100+0
680x=-&100+4
690y=-&100+8
700f=-&100+12
710sp=-&100+16
720pc_store=-&100+20
730T1mode=-&100+24
740T2mode=-&100+25
750T3mode=-&100+26
760T4mode=-&100+27
770T1=-&100+28
780T1R=-&100+32
790T2=-&100+36
800T2R=-&100+40
810T3=-&100+44
820T3R=-&100+48
830T4=-&100+52
840T4R=-&100+56
850screen=-&100+60
860screenR=-&100+64
870min=-&100+68
880sound_timer=-&100+72
890ifr=-&100+76
900ier=-&100+77
910ifr2=-&100+78
920ier2=-&100+79
930arc_screenstart=-&100+80
940tamper=-&100+84
950cursor_tamper=-&100+88
960ROMSEL_ON=-&100+92
970rom=-&100+96
980ROMRAM=-&100+100
990fe20=-&100+116
1000tape_handle=-&100+117
1010crt_regs=-&100+120
1020scratch=-&100+140
1030pal_regs=-&100+148
1040Palette=-&100+164
1050ACCCON=-&100+172
1060patch_on=-&100+176
1070pal_tamper=-&100+177
1080lastmode=-&100+178
1090fe10=-&100+179
1100tape_count=-&100+180
1110key_addr=-&100+184
1120screenstart_tamper=-&100+188
1130screenstart_previous=-&100+192
1140speedR=-&100+196
1150
1160enD=-&100+200 : REM don't go past this
1170
1180FORp=4 TO 6 STEP 2
1190div%=0
1200O%=code
1210l%=0
1220P%=0
1230opcode%=0
1240[OPTp
1250.Oa EQUD 0
1260.Ox EQUD 0
1270.Oy EQUD 0
1280.Of EQUD 0
1290.Osp EQUD 0
1300.Opc_store EQUD 0
1310.start_offset EQUD start
1320.trace EQUD 0
1330.trace2 EQUD 0
1340.init_addr EQUD init
1350.crt_addr EQUD 0 ; was crt_regs
1360.T1_addr EQUD 0 ; was T1
1370.ifr_addr EQUD 0 ; ifr
1380.column_counter_addr EQUD column_counter
1390.ROMSEL_addr EQUD 0 ; ROMSEL
1400.Palette_addr EQUD 0 ; Palette
1410.speed_addr EQUD screen_count+4
1420.elite_addr EQUD 0 ; elite
1430.opco_addr EQUD opcode(0) ; opcodetable
1440.bcd_addr EQUD bcd(0)
1450.sheila_writetab_addr EQUD sheila_writetab
1460.sheila_readtab_addr EQUD sheila_readtab
1470.sound_vectors_addr EQUD sound_buffs_addr
1480.patch_addr EQUD patch_screen
1490
1500.init ; only called once, before code called
1510ADR R0,0
1520;LDR R1,opco_addr
1530;ADD R1,R1,R0
1540;LDR R2,bcd_addr
1550;ADD R2,R2,R0
1560LDR R5,sheila_writetab_addr
1570ADD R5,R5,R0
1580LDR R6,sheila_readtab_addr
1590ADD R6,R6,R0
1600MOV R3,#255
1610.init_loop
1620;LDR R4,[R1,R3,LSL#2]
1630;ADD R4,R4,R0
1640;STR R4,[R1,R3,LSL#2]
1650;LDR R4,[R2,R3,LSL#2]
1660;ADD R4,R4,R0
1670;STR R4,[R2,R3,LSL#2]
1680LDR R4,[R5,R3,LSL#2]
1690ADD R4,R4,R0
1700STR R4,[R5,R3,LSL#2]
1710LDR R4,[R6,R3,LSL#2]
1720ADD R4,R4,R0
1730STR R4,[R6,R3,LSL#2]
1740SUBS R3,R3,#1
1750BPL init_loop
1760MOV PC,R14
1770
1780.start
1790STMFD R13!,{R1-R12,R14}
1800STR R13,return_addr
1810STR R0,roms_addr
1820;LDR R0,crt_addr
1830;ADR R1,0
1840;ADD R0,R0,R1
1850;SWI "6502_Init"
1860
1870BL blank_cursor
1880
1890MOV R0,#&9C00 : ADD R0,R0,#&40
1900STR R0,[mem,#screenR]
1910
1920SWI "6502_Getkeyaddr"
1930STR R0,[mem,#key_addr]
1940
1950ADR R0,block1
1960ADD R1,R0,#8
1970SWI "OS_ReadVduVariables"
1980LDR R9,[R1] ; screenstart
1990STR R9,[mem,#arc_screenstart]
2000MOV R9,#1
2010STRB R9,[mem,#tamper]
2020STRB R9,[mem,#pal_tamper]
2030STRB R9,[mem,#cursor_tamper]
2040
2050LDR time,[mem,#min]
2060LDR A,[mem,#a]
2070LDR X,[mem,#x]
2080LDR Y,[mem,#y]
2090LDR SP,[mem,#sp] : ORR SP,SP,#1
2100LDR F,[mem,#f]
2110LDR zpc,[mem,#pc_store]
2120
2130BL recalc_wrap
2140LDRB R0,[mem,#patch_on]
2150AND R0,R0,#%11111
2160BIC F,F,#&FF00
2170ORR F,F,R0,LSL#8
2180
2190;MOV time,#0
2200
2210LDRB R0,fe08_read
2220BIC R0,R0,#&81
2230STRB R0,fe08_read
2240
2250ADR R0,0
2260TST F,#%1000
2270LDREQ table,opco_addr
2280LDRNE table,bcd_addr
2290ADD table,table,R0
2300;SWI "6502_ReInit"
2310;SWI "6502_UpdateScreen
2320BL poke_updatepixelV
2330BL updatescreen
2340B fetch2
2350
2360.reset_bcdflag
2370ADR R1,0
2380TST F,#%1000
2390LDREQ table,opco_addr
2400LDRNE table,bcd_addr
2410ADD table,table,R1
2420MOV PC,R14
2430
2440.block1
2450EQUD 149 : EQUD -1
2460.block2
2470EQUD 0 : EQUD 0
2480
2490.screen_count
2500EQUD 0
2510EQUD 0
2520
2530.reg_comp
2540EQUD &FFEE << 16
2550
2560.trace_on
2570MOV R12,#1
2580STRB R12,trace
2590MOV PC,R14
2600
2610.show_regs
2620
2630;SWI "6502_Checkkdata"
2640LDR R0,[mem,#key_addr]
2650LDRB R0,[R0,#-4]
2660
2670
2680CMP R0,#&1F ; Insert
2690MOVEQ R1,#1
2700STREQ R1,trace2
2710
2720LDRB R0,trace2
2730CMP R0,#1
2740MOVNE PC,R14
2750
2760;LDR R0,reg_comp
2770;CMP R0,zpc
2780;MOVEQ R0,#1
2790;STREQB R0,trace
2800
2810;ADD R12,mem,#&DF00
2820;LDRB R12,[R12,#&DA]
2830;CMP R12,#0
2840;MOVEQ R12,#1
2850;STREQB R12,trace
2860
2870;LDRB R0,trace
2880;CMP R0,#1
2890;MOVNE PC,14
2900
2910FNshowregs
2920MOV PC,R14
2930
2940.read_ifr
2950LDRB R0,[mem,#ifr]
2960
2970LDR R1,[mem,#min]
2980SUB R1,R1,time
2990LDR R12,[mem,#screen]
3000SUB R12,R12,R1
3010CMP R12,#10
3020ORRLT R0,R0,#%10 ; vsync
3030;
3040;
3050; CMP zpc,#&8000 << 16
3060; ORRLT R0,R0,#%10 ; vsync
3070
3080
3090LDRB R1,[mem,#ier]
3100BIC R0,R0,#&80
3110ANDS R1,R1,R0
3120ORRNE R0,R0,#&80
3130
3140MOV PC,R14
3150
3160.read_ier
3170LDRB R0,[mem,#ier]
3180ORR R0,R0,#&80
3190MOV PC,R14
3200
3210.read_ifr2
3220LDRB R0,[mem,#ifr2]
3230LDRB R1,[mem,#ier2]
3240BIC R0,R0,#&80
3250ANDS R1,R1,R0
3260ORRNE R0,R0,#&80
3270MOV PC,R14
3280
3290.read_ier2
3300LDRB R0,[mem,#ier2]
3310ORR R0,R0,#&80
3320MOV PC,R14
3330
3340.IOpodule_Read
3350AND R0,R2,#&F
3360SWI "6502_ReadSheila"
3370MOV PC,R14
3380
3390.ldrb41
3400
3410SUB R12,mem,#512 ; sheila
3420LDRB R1,[R12,#&C] ; PCR
3430LDRB R2,[mem,#ifr]
3440AND R13,R1,#%1110
3450TEQ R13, #%0010
3460TEQNE R13, #%0110
3470BICEQ R2,R2,#%11
3480BICNE R2,R2,#%10
3490STRB R2,[mem,#ifr]
3500
3510LDRB R0,[R12,#&4F]
3520MOV PC,R14
3530
3540.ldrb4F
3550
3560SUB R12,mem,#512 ; sheila
3570LDRB R0,[R12,#&4F]
3580MOV PC,R14
3590
3600
3610.readT4low_count
3620LDRB R1,[mem,#ifr2]
3630BIC R1,R1, #%00100000
3640STRB R1,[mem,#ifr2]
3650LDR R0,[mem,#T4]
3660LDR R1,[mem,#min]
3670SUB R0,R0,R1,LSL#15
3680ADD R0,R0,time,LSL#15
3690TST R0,#1 << 15 ; ???
3700SUBNE time,time,#1
3710MOV R0,R0,LSR#16
3720AND R0,R0,#&FF
3730MOV PC,R14
3740
3750.readT4high_count
3760LDR R0,[mem,#T4]
3770LDR R1,[mem,#min]
3780SUB R0,R0,R1,LSL#15
3790ADD R0,R0,time,LSL#15
3800TST R0,#1 << 15 ; ???
3810SUBNE time,time,#1
3820MOV R0,R0,LSR#24
3830MOV PC,R14
3840
3850.readT3low_count
3860LDR R1,[mem,#ifr2]
3870BIC R1,R1, #%1 << 6
3880STRB R1,[mem,#ifr2] ; clear T3 interrupt flag
3890LDR R0,[mem,#T3]
3900LDR R1,[mem,#min]
3910SUB R0,R0,R1,LSL#15
3920ADD R0,R0,time,LSL#15
3930TST R0,#1 << 15 ; ???
3940SUBNE time,time,#1
3950MOV R0,R0,LSR#16
3960AND R0,R0,#&FF
3970MOV PC,R14
3980
3990.readT3high_count
4000LDR R0,[mem,#T3]
4010LDR R1,[mem,#min]
4020SUB R0,R0,R1,LSL#15
4030ADD R0,R0,time,LSL#15
4040TST R0,#1 << 15 ; ???
4050SUBNE time,time,#1
4060MOV R0,R0,LSR#24
4070MOV PC,R14
4080
4090.readT3low_latch
4100LDRB R0,[mem,#T3R+2]
4110MOV PC,R14
4120
4130.readT3high_latch
4140LDRB R0,[mem,#T3R+3]
4150MOV PC,R14
4160
4170.ACRtemp
4180EQUD 0
4190
4200.writeACR2
4210;MOV R0,#0
4220;STRB R0,[mem,#T3mode]
4230SUB R0,mem,#512
4240LDRB R1,[R0,#&60]
4250ORR R1,R1,#&80
4260STRB R1,[R0,#&60]
4270;MOV R0,#1
4280;STRB R0,ACRtemp
4290MOV PC,R14
4300
4310.writeT3low_latch
4320STRB R0,[mem,#T3R+2]
4330MOV PC,R14
4340
4350.writeT3high_count
4360STRB R0,[mem,#T3R+3]
4370LDR R0,[mem,#T3R]
4380ADD R0,R0,#2 << 16
4390
4400CMP R0,time,LSL#15 ; fix Exile's speech
4410
4420BHI skip_T3adjust
4430LDRB R2,[mem,#ier2]
4440
4450TST R2,#%01000000
4460MOVNE time,R0,LSR#15
4470
4480.skip_T3adjust
4490LDR R1,[mem,#min]
4500ADD R0,R0,R1,LSL#15
4510SUB R0,R0,time,LSL#15
4520STR R0,[mem,#T3]
4530LDRB R1,[mem,#ifr2]
4540BIC R1,R1, #%1 << 6
4550STRB R1,[mem,#ifr2] ; clear T3 interrupt flag
4560;SUB R0,R0,#&D
4570SUB R0,mem,#512 ; sheila
4580
4590
4600LDRB R1,[R0,#&6B]
4610EOR R1,R1,#1<<7
4620ANDS R1,R1,#&C0
4630LDREQB R1,[R0,#&60]
4640BICEQ R1,R1,#&80
4650STREQB R1,[R0,#&60]
4660
4670LDRB R12,[mem,#crt_regs+9]
4680CMP R12,#3
4690MOVEQ PC,R14 ; fortress fudge
4700
4710MOV R0,#1 : STRB R0,[mem,#T3mode]
4720MOV PC,R14
4730
4740.writeT3high_latch
4750STRB R0,[mem,#T3R+3]
4760MOV PC,R14
4770
4780.writeT4low_latch
4790STRB R0,[mem,#T4R+2]
4800MOV PC,R14
4810
4820.writeT4high_count
4830LDRB R1,[mem,#T4R+2]
4840ADD R1,R1,R0,LSL#8
4850MOV R1,R1,LSL#16
4860LDR R0,[mem,#min]
4870ADD R1,R1,R0,LSL#15
4880SUB R1,R1,time,LSL#15
4890;ADD R1,R1,#2 << 16
4900ADD R1,R1,#1 << 16
4910STR R1,[mem,#T4]
4920LDRB R1,[mem,#ifr2]
4930BICS R1,R1, #%001 << 5
4940STRB R1,[mem,#ifr2]
4950MOV R0,#1 : STRB R0,[mem,#T4mode]
4960MOV PC,R14
4970
4980.readT2low_count
4990LDRB R1,[mem,#ifr]
5000BIC R1,R1, #%101 << 5
5010STRB R1,[mem,#ifr] ; clear T2 interrupt flag
5020LDR R0,[mem,#T2]
5030LDR R1,[mem,#min]
5040SUB R0,R0,R1,LSL#15
5050ADD R0,R0,time,LSL#15
5060TST R0,#1 << 15 ; ???
5070SUBNE time,time,#1
5080MOV R0,R0,LSR#16
5090AND R0,R0,#&FF
5100MOV PC,R14
5110
5120.readT2high_count
5130LDR R0,[mem,#T2]
5140LDR R1,[mem,#min]
5150SUB R0,R0,R1,LSL#15
5160ADD R0,R0,time,LSL#15
5170TST R0,#1 << 15 ; ???
5180SUBNE time,time,#1
5190MOV R0,R0,LSR#24
5200MOV PC,R14
5210
5220.readT1low_count
5230LDRB R1,[mem,#ifr]
5240BIC R1,R1, #%1 << 6
5250STRB R1,[mem,#ifr] ; clear T1 interrupt flag
5260LDR R0,[mem,#T1]
5270LDR R1,[mem,#min]
5280SUB R0,R0,R1,LSL#15
5290ADD R0,R0,time,LSL#15
5300TST R0,#1 << 15 ; ???
5310SUBNE time,time,#1
5320MOV R0,R0,LSR#16
5330AND R0,R0,#&FF
5340MOV PC,R14
5350
5360.readT1high_count
5370LDR R0,[mem,#T1]
5380LDR R1,[mem,#min]
5390SUB R0,R0,R1,LSL#15
5400ADD R0,R0,time,LSL#15
5410TST R0,#1 << 15 ; ???
5420SUBNE time,time,#1
5430MOV R0,R0,LSR#24
5440MOV PC,R14
5450
5460.readT1low_latch
5470LDRB R0,[mem,#T1R+2]
5480MOV PC,R14
5490
5500.readT1high_latch
5510LDRB R0,[mem,#T1R+3]
5520MOV PC,R14
5530
5540.writeT1low_latch
5550STRB R0,[mem,#T1R+2]
5560MOV PC,R14
5570
5580.writeT1high_count
5590STRB R0,[mem,#T1R+3]
5600LDR R0,[mem,#T1R]
5610LDR R1,[mem,#min]
5620ADD R0,R0,R1,LSL#15
5630SUB R0,R0,time,LSL#15
5640ADD R0,R0,#2 << 16
5650STR R0,[mem,#T1]
5660LDR R1,[mem,#ifr]
5670BIC R1,R1, #%1 << 6
5680STRB R1,[mem,#ifr] ; clear T1 interrupt flag
5690SUB R0,mem,#512 ; sheila
5700LDRB R1,[R0,#&40]
5710BIC R1,R1,#&80
5720STRB R1,[R0,#&40]
5730MOV R0,#1 : STRB R0,[mem,#T1mode]
5740MOV PC,R14
5750
5760.writeT1high_latch
5770STRB R0,[mem,#T1R+3]
5780MOV PC,R14
5790
5800.writeT2low_latch
5810STRB R0,[mem,#T2R+2]
5820MOV PC,R14
5830
5840.writeT2high_count
5850LDRB R1,[mem,#T2R+2]
5860ADD R1,R1,R0,LSL#8
5870MOV R1,R1,LSL#16
5880LDR R0,[mem,#min]
5890ADD R1,R1,R0,LSL#15
5900SUB R1,R1,time,LSL#15
5910ADD R1,R1,#2 << 16
5920STR R1,[mem,#T2]
5930LDR R1,[mem,#ifr]
5940BICS R1,R1, #%101 << 5
5950STRB R1,[mem,#ifr] ; clear T2 interrupt flag
5960MOV R0,#1 : STRB R0,[mem,#T2mode]
5970MOV PC,R14
5980
5990;.T1mode
6000;EQUD 1
6010;.T2mode
6020;EQUD 0
6030;.T3mode
6040;EQUD 1
6050;.T4mode
6060;EQUD 0
6070;.T1
6080;EQUD &1234 << 16
6090;.T1R
6100;EQUD 20000 << 16
6110;.T2
6120;EQUD 98765 << 16
6130;.T2R
6140;EQUD 255 << 16
6150;.T3
6160;EQUD 6777 << 16
6170;.T3R
6180;EQUD 6777 << 16
6190;.T4
6200;EQUD 7380 << 16
6210;.T4R
6220;EQUD 255 << 16
6230;.screen
6240;EQUD 432
6250;.screenR
6260;EQUD 40000
6270;.min
6280;EQUD 200
6290;.sound_timer
6300;EQUD 0
6310
6320
6330.keychk
6340EQUD 0
6350
6360.CLI
6370BIC F,F,#%100
6380ADD zpc,zpc,#1 << 16
6390LDRB R0,keychk
6400CMP R0,#0
6410BLEQ keyboard
6420;BL keyboard
6430FNfetch3(0,2)
6440
6450
6460
6470.fetch2
6480
6490LDR R0,[mem,#min]
6500SUB R0,R0,time
6510LDR R1,[mem,#sound_timer]
6520SUB R1,R1,R0
6530STR R1,[mem,#sound_timer]
6540
6550
6560MOV R0,#0 : STR R0,keychk
6570LDR R0,[mem,#min]
6580SUB R0,R0,time ; ***
6590LDR R1,[mem,#screen]
6600SUBS R1,R1,R0
6610STRGT R1,[mem,#screen]
6620BLLE vsync
6630
6640LDR R0,[mem,#min]
6650SUB R0,R0,time ; ***
6660LDR R1,speed
6670SUBS R1,R1,R0
6680STRGT R1,speed
6690BLLE speed_control
6700
6710; LDR R0,[mem,#T1mode]
6720; TST R0,#%1
6730; BEQ skip_timer1
6740
6750LDR R0,[mem,#min]
6760SUB R0,R0,time ; ***
6770LDR R1,[mem,#T1]
6780SUBS R1,R1,R0,LSL#15
6790STRGT R1,[mem,#T1]
6800BLLE timer1
6810.skip_timer1
6820
6830; LDR R0,[mem,#T2mode]
6840; TST R0,#%1
6850; BEQ skip_timer2
6860
6870LDR R0,[mem,#min]
6880SUB R0,R0,time ; ***
6890LDR R1,[mem,#T2]
6900SUBS R1,R1,R0,LSL#15
6910STR R1,[mem,#T2]
6920BLLE timer2
6930.skip_timer2
6940
6950; LDR R0,[mem,#T3mode]
6960; TST R0,#%1
6970; BEQ skip_timer3
6980
6990LDR R0,[mem,#min]
7000SUB R0,R0,time ; ***
7010LDR R1,[mem,#T3]
7020SUBS R1,R1,R0,LSL#15
7030STRGT R1,[mem,#T3]
7040BLLE timer3
7050.skip_timer3
7060
7070; LDR R0,[mem,#T4mode]
7080; TST R0,#%1
7090; MVNEQ R1,#0 ; -1
7100; STREQ R1,T4
7110; BEQ skip_timer4
7120
7130LDR R0,[mem,#min]
7140SUB R0,R0,time ; ***
7150LDR R1,[mem,#T4]
7160SUBS R1,R1,R0,LSL#15
7170STR R1,[mem,#T4]
7180BLLE timer4
7190.skip_timer4
7200
7210LDR R0,[mem,#min]
7220SUB R0,R0,time
7230LDR R1,[mem,#tape_count]
7240SUBS R1,R1,R0
7250STRGT R1,[mem,#tape_count]
7260BLLE tape_fetch
7270
7280LDRB R1,[mem,#ifr]
7290LDRB R2,[mem,#ifr2]
7300LDRB R12,[mem,#ier] : AND R1,R1,R12
7310LDRB R12,[mem,#ier2]: AND R2,R2,R12
7320;BIC R1,R1,#&80 : ;BIC R2,R2,#&80
7330
7340
7350;LDRB R0,[mem,#ier]
7360;BIC R0,R0,#%1 ; ignore keyboard interrupt
7370;ANDS R0,R0,R1
7380;ORRNE R1,R1,#&80
7390;LDRB R0,[mem,#ier2]
7400;ANDS R0,R0,R2
7410;ORRNE R2,R2,#&80
7420
7430TST F,#%100
7440BNE skip_do_interrupt
7450;TST R1,#&80
7460;TSTEQ R2,#&80
7470ANDS R1,R1,#%01111111
7480ANDEQS R2,R2,#%01111111
7490BEQ skip_do_interrupt
7500;CMP R13,#1
7510;BNE skip_do_interrupt
7520
7530.do_interrupt
7540FNdo_interrupt
7550
7560.skip_do_interrupt
7570
7580;BL keyboard MOVED TO CLI!!!
7590BL keys2
7600.skip_keys
7610LDR time,[mem,#T1]
7620MOV time,time,LSR#15
7630LDR R1,[mem,#screen]
7640CMP R1,#0 : MOVEQ R1,time
7650CMP R1,time
7660MOVLT time,R1
7670LDRB R1,[mem,#T2mode]
7680CMP R1,#0
7690BEQ skipT2
7700LDR R1,[mem,#T2]
7710
7720;RJW
7730MOVS R1,R1,LSR#15
7740MOVEQ R1,time
7750CMP R1,time
7760MOVLT time,R1
7770.skipT2
7780LDR R1,[mem,#T3]
7790MOVS R1,R1,LSR#15
7800
7810; RJW
7820MOVEQ R1,time
7830CMP R1,time
7840MOVLT time,R1
7850LDRB R1,[mem,#T4mode]
7860CMP R1,#0
7870BEQ skipT4
7880LDR R1,[mem,#T4]
7890
7900; RJW
7910MOVS R1,R1,LSR#15
7920MOVEQ R1,time
7930CMP R1,time
7940MOVLT time,R1
7950.skipT4
7960;CMP time,#0 : ;MOVEQ time,#1
7970SUB time,time,#4
7980STR time,[mem,#min]
7990FNfetch2
8000
8010.interrupt
8020
8030TST F,#%100
8040MOVNE PC,R14
8050
8060LDRB R1,[mem,#ifr]
8070LDRB R2,[mem,#ifr2]
8080LDRB R12,[mem,#ier] : AND R1,R1,R12
8090LDRB R12,[mem,#ier2]: AND R2,R2,R12
8100
8110ANDS R1,R1,#%01111111
8120ANDEQS R2,R2,#%01111111
8130MOVEQ PC,R14
8140
8150FNdo_interrupt
8160
8170MOV PC,R14
8180
8190.F10temp
8200EQUD 0
8210
8220.F10
8230SWI "6502_Getkdata"
8240STR R14,F10temp
8250MOV R0,#255
8260STRB R0,[mem,#lastmode]
8270BL updatescreen
8280BL force_update_pal
8281BL cursor
8290LDR PC,F10temp
8300
8310;.fetch3
8320.keys2
8330;SWI "6502_Checkkdata"
8340LDR R0,[mem,#key_addr]
8350LDRB R0,[R0,#-4]
8360
8370
8380CMP R0,#&1F ; Insert
8390MOVEQ R1,#1
8400STREQ R1,trace2
8410CMP R0,#10 ; F10
8420BEQ F10
8430CMP R0,#11 ; F11
8440CMPNE R0,#12 ; F12
8450CMPNE R0,#15 ; break
8460BEQ raw_exit2
8470MOV PC,R14
8480
8490.keyboard
8500MOV R0,#1 : STR R0,keychk
8510
8520
8530;SWI "6502_Checkkdata"
8540LDR R0,[mem,#key_addr]
8550LDRB R0,[R0,#-4]
8560CMP R0,#&FF : MOVEQ PC,R14
8570
8580
8590SWI "6502_Getkdata"
8600;CMP R0,#&FF : ;MOVEQ PC,R14
8610CMP R0,#&1F ; Insert
8620MOVEQ R1,#1
8630STREQ R1,trace2
8640CMP R0,#10 ; F10
8650BEQ F10
8660CMP R0,#15
8670CMPNE R0,#12
8680CMPNE R0,#11 ; F11
8690BEQ raw_exit
8700
8710;CMP R0,#0 ; escape
8720;LDREQB R0,[mem,#&FF]
8730;ORREQ R0,R0,#&80
8740;STREQB R0,[mem,#&FF]
8750LDRB R0,[R1,R0]
8760CMP R0,#&FF
8770;BEQ not_keyboard
8780MOVEQ PC,R14
8790
8800;B not_keyboard
8810CMP R0,#10 ; shift, ctrl
8820MOVLT PC,R14
8830LDRB R1,[mem,#ifr]
8840ORR R1,R1,#%1 ; interrupt is from keyboard
8850STRB R1,[mem,#ifr]
8860LDRB R0,[mem,#ier]
8870TST R0,#%1
8880MOVEQ PC,R14
8890FNdo_interrupt
8900MOV PC,R14
8910
8920
8930;.no_interrupt
8940;LDRB R0,trace2
8950;CMP R0,#0
8960;BEQ notrace2
8970;FNshowregs
8980;.notrace2
8990;FNfetch2
9000
9010.define_cursor
9020MOV R1,#0 : STRB R1,cursor_state
9030.define_cursor2
9040LDRB R1,cursor_state
9050CMP R1,#0:MOVNE PC,R14
9060
9070LDRB R1,[mem,#crt_regs+10] ; cursor start
9080
9090EOR R12,R1,#%100000
9100TST R12,#%1100000
9110BEQ blank_cursor
9120
9130LDRB R2,[mem,#crt_regs+11] ; cursor end
9140AND R1,R1,#31
9150AND R2,R2,#31
9160
9170SUBS R12,R2,R1
9180BLT blank_cursor
9190
9200
9210LDRB R12,[mem,#fe20]
9220EOR R12,R12,#%100000
9230
9240TST R12,#%1000
9250MOVEQ R13,#2 ; mode 5
9260MOVNE R13,#1
9270
9280MOV R0,#1
9290MOV R0,R0,LSL R13
9300TSTEQ R12,#%100000
9310MOVEQ R0,#8 ; mode 2
9320MOVEQ R13,#3
9330STRB R0,cursor_width
9340
9350TST R12,#%10 ; teletext
9360MVNNE R12,#7
9370MOVEQ R12,#1
9380
9390ADD R2,R2,R12
9400STRB R2,cursor_height
9410
9420;MOV R0,#1
9430;MOV R0,R0,LSL R13
9440;STRB R0,cursor_width
9450
9460
9470ADR R0,cursor_data
9480SUB R0,R0,R1,LSL R13
9490SUB R0,R0,R12,LSL R13
9500STR R0,cursor_block+6
9510
9520MOV R0,#21
9530ADR R1,cursor_block
9540SWI "OS_Word"
9550MOVS PC,R14
9560
9570.blank_cursor
9580MOV R1,#1 : STRB R1,cursor_state
9590.blank_cursor2
9600
9610ADR R1,cursor_block
9620ADR R0,blank_data
9630STR R0,cursor_block+6
9640MOV R0,#21
9650SWI "OS_Word"
9660MOV PC,R14
9670
9680.cursor_state
9690EQUD 0
9700
9710.cursor_flash
9720EQUD 0
9730.flash_state
9740EQUD 0
9750
9760;.not_keyboard
9770EQUW 0
9780.cursor_block
9790EQUB 0
9800EQUB 2 ; shape number
9810.cursor_width
9820EQUB 2 ; width in bytes
9830.cursor_height
9840EQUB 9 ; height in pixels
9850EQUB 0
9860EQUB 0
9870EQUD 0 ; address of data
9880
9890
9900ALIGN
9910.blank_data
9920EQUD 0
9930EQUD 0
9940EQUD 0
9950EQUD 0
9960EQUD 0
9970EQUD 0
9980EQUD 0
9990EQUD 0
10000EQUD 0
10010EQUD 0
10020EQUD 0
10030EQUD 0
10040EQUD 0
10050EQUD 0
10060EQUD 0
10070EQUD 0
10080EQUD 0
10090EQUD 0
10100EQUD 0
10110EQUD 0
10120EQUD 0
10130EQUD 0
10140EQUD 0
10150EQUD 0
10160EQUD 0
10170EQUD 0
10180EQUD 0
10190EQUD 0
10200EQUD 0
10210EQUD 0
10220EQUD 0
10230EQUD 0
10240.cursor_data
10250EQUD &FFFFFFFF
10260EQUD &FFFFFFFF
10270EQUD &FFFFFFFF
10280EQUD &FFFFFFFF
10290EQUD &FFFFFFFF
10300EQUD &FFFFFFFF
10310EQUD &FFFFFFFF
10320EQUD &FFFFFFFF
10330EQUD &FFFFFFFF
10340EQUD &FFFFFFFF
10350EQUD &FFFFFFFF
10360EQUD &FFFFFFFF
10370EQUD &FFFFFFFF
10380EQUD &FFFFFFFF
10390EQUD &FFFFFFFF
10400EQUD &FFFFFFFF
10410EQUD &FFFFFFFF
10420EQUD &FFFFFFFF
10430EQUD &FFFFFFFF
10440EQUD &FFFFFFFF
10450EQUD &FFFFFFFF
10460EQUD &FFFFFFFF
10470EQUD &FFFFFFFF
10480EQUD &FFFFFFFF
10490EQUD &FFFFFFFF
10500EQUD &FFFFFFFF
10510EQUD &FFFFFFFF
10520EQUD &FFFFFFFF
10530EQUD &FFFFFFFF
10540EQUD &FFFFFFFF
10550EQUD &FFFFFFFF
10560EQUD &FFFFFFFF
10570
10580.cursor7
10590
10600LDRB R0,[mem,#crt_regs+14]
10610LDRB R1,[mem,#crt_regs+15]
10620ADD R0,R1,R0,LSL#8
10630
10640LDRB R1,[mem,#crt_regs+12] : ;AND R1,R1,#%1111
10650LDRB R2,[mem,#crt_regs+13]
10660ADD R2,R2,R1,LSL#8
10670SUBS R0,R0,R2
10680MOVMI R0,#0
10690
10700;LDRB R12,[mem,#crt_regs+1] ; horiz. chars
10710;MOV R12,#40
10720
10730;FNdivmod(0,12,1,2,13) ; R0 = R0 MOD R12
10740 ; R2 = R0 DIV R12
10750;RSB R2,R2,#25
10760;MOV R2,R2,LSL#5
10770;ADD R2,R2,R2,LSR#2
10780;MOV R0,R0,LSL#5
10790;ADD R0,R0,R2,LSL#16
10800; We know that R0<1000
10810; R0 = R0 MOD 40
10820; R2 = R0 DIV 40
10830;FNdivmod(0,12,1,2,13)
10840MOV R2,#((25<<5)+(25<<3))<<16
10850CMP R0,#640
10860SUBGE R0,R0,#640
10870SUBGE R2,R2,#((1<<9)+(1<<7))<<16
10880CMP R0,#320
10890SUBGE R0,R0,#320
10900SUBGE R2,R2,#((1<<8)+(1<<6))<<16
10910CMP R0,#160
10920SUBGE R0,R0,#160
10930SUBGE R2,R2,#((1<<7)+(1<<5))<<16
10940CMP R0,#80
10950SUBGE R0,R0,#80
10960SUBGE R2,R2,#((1<<6)+(1<<4))<<16
10970CMP R0,#40
10980SUBGE R0,R0,#40
10990SUBGE R2,R2,#((1<<5)+(1<<3))<<16
11000
11010
11020ADD R0,R2,R0,LSL#5
11030STR R0,osword21_5_block1
11040ADR R1,osword21_5_block
11050MOV R0,#21
11060SWI "OS_Word" ; set pointer position
11070;MOV PC,R14
11071B define_cursor2
11080
11090;B cursor_cont
11100
11110.padding_to_align_osword
11120EQUB 0 : EQUB 0 : EQUB 0
11130.osword21_5_block
11140EQUB 5
11150.osword21_5_block1
11160EQUD 0
11170
11180EOR R0,R0,#&20 : ADD R0,R0,#&74 : AND R0,R0,#&FF
11190
11200
11210.cursor
11220MOV R0,#0 : STR R0,[mem,#cursor_tamper]
11230
11240\LDRB R1,[mem,#cursor_on]
11250\CMP R1,#0:\MOVNE PC,R14
11260TST F,#1 << 10 ; cursor on?
11270MOVEQ PC,R14
11280
11290LDRB R0,[mem,#fe20]
11300
11310TST R0,#%11100000
11320BEQ blank_cursor
11330
11340TST R0,#%10 ; teletext
11350BNE cursor7
11360
11370LDRB R0,[mem,#crt_regs+14]
11380LDRB R1,[mem,#crt_regs+15]
11390ADD R0,R1,R0,LSL#8
11400
11410LDRB R1,[mem,#crt_regs+12] : AND R1,R1,#%1111
11420LDRB R2,[mem,#crt_regs+13]
11430ADD R2,R2,R1,LSL#8
11440SUBS R0,R0,R2
11450MOVMI R0,#0
11460
11470.cursor_cont
11480
11490LDRB R12,[mem,#crt_regs+1] ; horiz. chars
11500
11510CMP R12,#0 : MOVEQ PC,R14
11520
11530;FNdivmod(0,12,1,2,13) ; R0 = R0 MOD R12
11540 ; R2 = R0 DIV R12
11550;RSB R2,R2,#32
11560;MOV R2,R2,LSL#5
11570
11580; We know R0<32*R12
11590; R0 = R0 MOD R12
11600; R2 = R0 DIV R12
11610MOV R2,#32<<21
11620CMP R0,R12,LSL#4
11630SUBGE R0,R0,R12,LSL#4
11640SUBGE R2,R2,#16<<21
11650CMP R0,R12,LSL#3
11660SUBGE R0,R0,R12,LSL#3
11670SUBGE R2,R2,#8<<21
11680CMP R0,R12,LSL#2
11690SUBGE R0,R0,R12,LSL#2
11700SUBGE R2,R2,#4<<21
11710CMP R0,R12,LSL#1
11720SUBGE R0,R0,R12,LSL#1
11730SUBGE R2,R2,#2<<21
11740CMP R0,R12
11750SUBGE R0,R0,R12
11760SUBGE R2,R2,#1<<21
11770
11780
11790LDRB R1,[mem,#fe20] : TST R1,#%10000 : MOVEQ R0,R0,LSL#1
11800;MOV R0,R0,LSL#4 ; these two surplus
11810;ADD R0,R0,R2,LSL#16 ;
11820ADD R0,R2,R0,LSL#4 ; this line missing in 1.30
11830STR R0,osword21_5_block1
11840ADR R1,osword21_5_block
11850MOV R0,#21
11860SWI "OS_Word" ; set pointer position
11870;MOV PC,R14
11871B define_cursor2
11880
11890.mono_time
11900EQUD 0
11910.speed
11920EQUD 0
11930
11940.speed_control
11950LDR R0,[mem,#speedR]
11960ADD R1,R1,R0
11970STR R1,speed
11980
11990LDR R1,mono_time
12000.mono_loop
12010SWI "OS_ReadMonotonicTime"
12020MOV R0,R0,LSR#1
12030CMP R0,R1
12040BEQ mono_loop
12050STR R0,mono_time
12060
12070MOV PC,R14
12080
12090
12100
12110.vsync
12120STR R14,vsyncR14
12130
12140
12150LDR R0,[mem,#screenR]
12160ADD R1,R1,R0
12170STR R1,[mem,#screen]
12180
12190LDRB R0,ldrb40_tamper
12200CMP R0,#1 : BLEQ ldrb40_update
12210
12220;BL trace_on
12230
12240;LDRB R1,screen_count
12250;SUBS R1,R1,#1
12260;LDRMIB R1,screen_count+4
12270;STRB R1,screen_count
12280LDR R0,[mem,#tamper]
12290CMP R0,#0
12300
12310BEQ no_tamper
12320MOV R0,#0
12330STR R0,[mem,#tamper]
12340;SWI "6502_UpdateScreen"
12350BL recalc_wrap
12360BL updatescreen
12370TST F,#1 << 10 ; cursor on?
12380BLNE define_cursor
12390BLNE cursor
12400.no_tamper
12410LDRB R0,[mem,#pal_tamper]
12420CMP R0,#0
12430BLNE update_pal
12440
12450
12460LDR R0,[mem,#cursor_tamper]
12470CMP R0,#0
12480BLNE cursor
12490
12500
12510
12520SUB R0,mem,#512 ; sheila
12530LDRB R1,[R0,#&20]
12540TST R1,#%10 ; teletext?
12550;SWINE "6502_UpdateScreen"
12560BLNE updatescreen
12570ADD R0,R0,#&4D
12580;LDRB R1,[R0]
12590;LDRB R2,[R0,#1]
12600LDRB R1,[mem,#ifr]
12610LDRB R2,[mem,#ier]
12620ORR R1,R1,#%10 ; interrupt is from vsync
12630TST R2,#%10 ; is vsync interrupt enabled?
12640ORRNE R1,R1,#&80
12650;STRB R1,[R0]
12660STRB R1,[mem,#ifr]
12670;BEQ no_interrupt
12680;FNfetch2
12690
12700;TST F,#1 << 9
12710;BEQ skip_exact
12720
12730;LDR R1,mono_time
12740;.mono_loop
12750;SWI "OS_ReadMonotonicTime"
12760;MOV R0,R0,LSR#1
12770;CMP R0,R1
12780;BEQ mono_loop
12790;STR R0,mono_time
12800
12810.skip_exact
12820
12830TST F,#1 << 10 ; cursor on?
12840LDREQ PC,vsyncR14
12850
12860LDRB R1,cursor_state
12870CMP R1,#0
12880LDRNE PC,vsyncR14
12890
12900LDRB R1,[mem,#crt_regs+10]
12910TST R1,#%1000000 ; cursor blinking enabled?
12920LDREQ PC,vsyncR14
12930
12940LDRB R0,cursor_flash
12950SUBS R0,R0,#1
12960STRB R0,cursor_flash
12970LDRGE PC,vsyncR14
12980
12990TST R1,#%100000
13000MOVEQ R0,#15
13010MOVNE R0,#31
13020STRB R0,cursor_flash
13030
13040LDR R14,vsyncR14
13050LDRB R0,flash_state
13060EOR R0,R0,#1
13070STRB R0,flash_state
13080CMP R0,#0 : BEQ blank_cursor2
13090B define_cursor2
13100
13110;LDR PC,vsyncR14
13120.vsyncR14
13130EQUD 0
13140
13150.ldrb40
13160
13170LDRB R2,ldrb40_value
13180BIC R0,R0,#%110000
13190ORR R0,R0,R2
13200MOV R1,#1
13210STRB R1,ldrb40_tamper
13220MOV PC,R14
13230
13240.ldrb40_update
13250MOV R0,#%110000
13260STRB R0,ldrb40_value
13270MOV R0,#0
13280STRB R0,ldrb40_tamper
13290TST F,#1<<9 ; joystick
13300MOVEQ PC,R14
13310SWI &63F40 ; "XJoystick_Read" ; joy 0
13320BVS ldrb40_mouse
13330AND R1,R0,#&10000
13340MOV R0,#1
13350SWI &63F40 ; "XJoystick_Read" ; joy 1
13360MOVVS R0,#0
13370AND R0,R0,#&10000
13380ADD R1,R1,R0,LSL#1
13390AND R1,R1,#&30000
13400MOV R1,R1,LSR#(16-4)
13410
13420EOR R2,R1,#%110000
13430
13440;ADD R13,mem,#&FE00
13450;LDRB R0,[R13,#&40]
13460;BIC R0,R0,#%110000
13470STRB R2,ldrb40_value
13480;ORR R0,R0,R2
13490
13500MOV PC,R14
13510
13520.ldrb40_tamper
13530EQUD 0
13540.ldrb40_value
13550EQUD 0
13560
13570.ldrb40_mouse
13580MOV R13,R3
13590SWI "OS_Mouse"
13600MOV R3,R13
13610
13620MOV R2,R2,LSR#1
13630RSB R2,R2,#3
13640MOV R2,R2,LSL#4
13650;ADD R13,mem,#&FE00
13660;LDRB R0,[R13,#&40]
13670;BIC R0,R0,#%110000
13680STRB R2,ldrb40_value
13690;ORR R0,R0,R2
13700
13710MOV PC,R14
13720
13730.write_ADC_status
13740
13750TST F,#1<<9 ; joystick
13760MOVEQ PC,R14
13770
13780
13790BIC R12,R0,#%11110000
13800
13810MOV R0,R0,LSR#1
13820AND R0,R0,#%1 ; joystick number
13830SWI &63F40 ; "XJoystick_Read"
13840BVS write_ADC_mouse
13850
13860
13870TST R12,#%1 ; left/right or up/down
13880MOVEQ R0,R0,LSR#8
13890ADD R0,R0,#127
13900AND R0,R0,#&FF
13910RSBEQ R0,R0,#255
13920
13930MOV R1,R0,LSR#2
13940AND R1,R1,#%110000
13950ORR R12,R12,R1
13960ORR R12,R12,#%1000000
13970
13980SUB R1,mem,#512 ; sheila
13990
14000STRB R12,[R1,#&C0]
14010STRB R12,[R1,#&18]
14020
14030STRB R0,[R1,#&C1]
14040STRB R0,[R1,#&19]
14050MOV R12,#0
14060STRB R12,[R1,#&C2]
14070STRB R12,[R1,#&1A]
14080
14090MOV PC,R14
14100
14110.write_ADC_mouse
14120
14130MOV R13,R3
14140SWI "OS_Mouse"
14150MOV R3,R13
14160
14170MOV R2,#1024
14180SUB R2,R2,#1
14190SUBS R0,R2,R0
14200MOVLT R0,#0
14210
14220;CMP R0,#1024
14230;MOVGE R0,#1024
14240;SUBGE R0,R0,#1
14250
14260TST R12,#%1 ; left/right or up/down
14270MOVNE R0,R1
14280
14290MOV R1,R0,LSL#4
14300AND R1,R1,#%110000
14310ORR R12,R12,R1
14320ORR R12,R12,#%1000000
14330
14340SUB R1,mem,#512 ; sheila
14350
14360STRB R12,[R1,#&C0]
14370STRB R12,[R1,#&18]
14380
14390MOV R12,R0,LSR#2
14400STRB R12,[R1,#&C1]
14410STRB R12,[R1,#&19]
14420MOV R12,R0,LSL#6
14430STRB R12,[R1,#&C2]
14440STRB R12,[R1,#&1A]
14450
14460MOV PC,R14
14470
14480
14490.timer1
14500LDR R0,[mem,#T1R]
14510ADD R1,R1,R0
14520ADD R1,R1,#2 << 16
14530STR R1,[mem,#T1]
14540
14550SUB R0,mem,#512 ; sheila
14560
14570LDRB R1,[R0,#&4B] ; FE4B
14580TST R1,#%01000000
14590MOVEQ R2,#0
14600STREQB R2,[mem,#T1mode]
14610
14620TST R1,#%10000000
14630LDRNEB R2,[R0,#&40] ; FE40
14640EORNE R2,R2,#&80
14650STRNEB R2,[R0,#&40] ; FE40
14660
14670LDRB R1,[mem,#ifr]
14680ORR R1,R1,#%01000000 ; interrupt is from timer 1
14690STRB R1,[mem,#ifr]
14700
14710MOV PC,R14
14720
14730.timer2
14740LDRB R0,[mem,#T2mode]
14750CMP R0,#0
14760MOVEQ PC,R14
14770MOV R0,#0
14780STRB R0,[mem,#T2mode]
14790
14800LDRB R1,[mem,#ifr]
14810ORR R1,R1,#%00100000
14820STRB R1,[mem,#ifr]
14830
14840MOV PC,R14
14850
14860.timer3
14870LDR R0,[mem,#T3R]
14880ADD R1,R1,R0
14890STR R1,[mem,#T3]
14900
14910SUB R0,mem,#512 ; sheila
14920
14930LDRB R1,[R0,#&6B]
14940TST R1,#%01000000
14950BNE T3mode_skip2
14960
14970LDRB R1,[mem,#T3mode]
14980CMP R1,#1
14990;SWINE &100+ASC"1"
15000;SWIEQ &100+ASC"0"
15010BNE T3mode_skip
15020
15030.T3mode_skip2
15040LDRB R1,[mem,#ifr2]
15050ORR R1,R1,#%01000000
15060STRB R1,[mem,#ifr2]
15070
15080
15090;LDRB R1,[R0,#&6B] ; FE6B
15100;TST R1,#%01000000
15110;MOVEQ R2,#0
15120;MOVNE R2,#1
15130;STREQB R2,[mem,#T3mode]
15140;SWIEQ &100+ASC"z"
15150
15160.T3mode_skip
15170MOV R2,#0
15180STRB R2,[mem,#T3mode]
15190
15200;LDRB R1,[R0,#&6B] ; FE6B
15210;TST R1,#%10000000
15220;LDRB R2,[R0,#&60] ; FE60
15230;EORNE R2,R2,#&80
15240;ORREQ R2,R2,#&80
15250;STRB R2,[R0,#&60] ; FE60
15260
15270LDRB R1,[R0,#&6B] ; FE6B
15280EOR R1,R1,#&C0
15290TST R1,#&C0
15300LDRB R2,[R0,#&60] ; FE60
15310EOREQ R2,R2,#&80
15320ORRNE R2,R2,#&80
15330STRB R2,[R0,#&60] ; FE60
15340
15350
15360MOV PC,R14
15370.return_addr
15380EQUD 0
15390
15400.roms_addr
15410EQUD 0
15420
15430.timer4
15440LDRB R1,[mem,#T4mode]
15450CMP R1,#0
15460MOVEQ PC,R14
15470MOV R0,#0
15480STRB R0,[mem,#T4mode]
15490
15500
15510LDRB R1,[mem,#ifr2]
15520ORR R1,R1,#%00100000 ; interrupt is from timer 4
15530STRB R1,[mem,#ifr2]
15540
15550MOV PC,R14
15560
15570
15580;.trace2
15590;EQUD 0
15600
15610.reset
15620;MOV R1,#1
15630;STR R1,trace
15640MOV R0,#15 : MOV R1,#0 : SWI "OS_Byte"
15650MOV R0,#&10000
15660SUB R0,R0,#4
15670LDR R0,[mem,R0]
15680MOV zpc,R0,LSL#16
15690BIC F,F,#%1000 ; clear Decimal mode
15700ORR F,F,#%100 ; set interrupt disable
15710FNfetch2
15720
15730
15740.exit
15750MOV R0,#0
15760.raw_exit2
15770SWI "6502_Getkdata"
15780.raw_exit
15790STR time,[mem,#min]
15800STR A,[mem,#a]
15810STR X,[mem,#x]
15820STR Y,[mem,#y]
15830STR SP,[mem,#sp]
15840STR F,[mem,#f]
15850STR zpc,[mem,#pc_store]
15860LDR R13,return_addr
15870LDMFD R13!,{R1-R12,PC}
15880;MOV PC,R14
15890
15900
15910.fe08_read
15920EQUB 0
15930.fe08_write
15940EQUB 0
15950.fe09
15960EQUB 0
15970;.fe10
15980;EQUB 0
15990ALIGN
16000.tbuffer
16010EQUD 0
16020
16030.tape_fetch
16040;LDR R0,[mem,#tapeR]
16050;MOV R0,#&3400 ; 2000000/(1200/8)~=1200 baud
16060MOV R0,#&6000
16070ADDS R1,R1,R0
16080MOVLE R1,#&6000
16090
16100LDRB R0,[mem,#fe10]
16110TST R0,#&80 ; is *Motor on?
16120MOVEQ R1,#&100000
16130
16140STR R1,[mem,#tape_count]
16150
16160MOVEQ PC,R14
16170
16180LDRB R1,[mem,#tape_handle]
16190CMP R1,#0
16200MOVEQ PC,R14
16210
16220.tape_get
16230SWI "XOS_BGet"
16240MOVVS R1,#0
16250STRVSB R1,[mem,#tape_handle]
16260MOVVS PC,R14
16270
16280BCC tape_skip10
16290
16300MOV R0,#1
16310MOV R2,#0
16320SWI "XOS_Args" ; rewind tape to start
16330MOVVS R1,#0
16340STRVSB R1,[mem,#tape_handle]
16350MOVVS PC,R14
16360
16370.tape_skip10
16380
16390CMP R0,#&FF
16400BNE not_FF
16410SWIEQ "XOS_BGet"
16420CMP R0,#&FF
16430BEQ not_FF
16440
16450LDRB R1,fe08_read
16460BIC R1,R1,#%100
16470AND R0,R0,#%100
16480ORR R1,R1,R0
16490;ORR R1,R1,#&80 ; ??
16500STRB R1,fe08_read
16510
16520CMP R0,#0
16530
16540;MOV R0,#&10000
16550;STR R0,[mem,#tape_count]
16560
16570;B do_interrupt
16580MOVEQ PC,R14
16590
16600ORR R1,R1,#&80
16610STRB R1,fe08_read
16620B do_interrupt
16630
16640.not_FF
16650STRB R0,fe09
16660
16670
16680LDRB R0,fe08_write
16690TST R0,#&80 ; receive interrupt enable bit
16700MOVEQ PC,R14
16710
16720LDRB R0,fe08_read
16730ORR R0,R0,#&81
16740STRB R0,fe08_read
16750
16760B do_interrupt
16770;MOV PC,R14
16780
16790.readFE08
16800;LDRB R1,tbuffer
16810;LDRB R0,[mem,#&C2]
16820;CMP R0,#1
16830LDRB R0,fe08_read
16840;CMPEQ R1,#ASC"*"
16850;ORREQ R0,R0,#%100
16860;BICNE R0,R0,#%100
16870MOV PC,R14
16880
16890.readFE09
16900LDRB R0,fe08_read
16910BIC R0,R0,#&81
16920STRB R0,fe08_read
16930LDRB R0,fe09
16940MOV PC,R14
16950
16960.writeFE08
16970STRB R0,fe08_write
16980MOV PC,R14
16990
17000.writeFE09
17010MOV PC,R14
17020
17030.readFE10
17040MOV R0,#&A2
17050MOV PC,R14
17060
17070.writeFE10
17080STRB R0,[mem,#fe10]
17090MOV PC,R14
17100
17110.dummy
17120MOV PC,R14
17130
17140;.ROMSEL
17150;EQUD 0
17160
17170;.rom ; ROM paged in
17180;EQUD 0
17190
17200;.ROMRAM ; which banks are RAM?
17210;EQUD 0 : ;EQUD 0 : ;EQUD 0 : ;EQUD 0
17220
17230;.ACCCON
17240;EQUD 0
17250
17260
17270.swap_main_shadow
17280
17290STMFD mem,{R0-R2,R4-R11,R14}
17300ADD R14,mem,#&3000
17310SUB R13,mem,#&10000
17320MOV R12,#&5000
17330.swap_loop
17340LDMIA R14,{R0-R2,R4-R5}
17350;LDR R0,[R14,#0]
17360;LDR R1,[R14,#4]
17370;LDR R2,[R14,#8]
17380;LDR R4,[R14,#12]
17390;LDR R5,[R14,#16]
17400
17410LDMIA R13,{R6-R10}
17420;LDR R6,[R13,#0]
17430;LDR R7,[R13,#4]
17440;LDR R8,[R13,#8]
17450;LDR R9,[R13,#12]
17460;LDR R10,[R13,#16]
17470
17480STMIA R13!,{R0-R2,R4-R5}
17490;STR R0,[R13,#0]
17500;STR R1,[R13,#4]
17510;STR R2,[R13,#8]
17520;STR R4,[R13,#12]
17530;STR R5,[R13,#16]
17540
17550STMIA R14!,{R6-R10}
17560;STR R6,[R14,#0]
17570;STR R7,[R14,#4]
17580;STR R8,[R14,#8]
17590;STR R9,[R14,#12]
17600;STR R10,[R14,#16]
17610
17620;ADD R14,R14,#20
17630;ADD R13,R13,#20
17640SUBS R12,R12,#20
17650BHI swap_loop
17660
17670LDMEA mem,{R0-R2,R4-R11,R14}
17680B swap_exit
17690
17700
17710.strb_rom_ret2 ; between C000 AND E000
17720LDRB R2,[mem,#ACCCON]
17730TST R2,#%1000
17740MOVEQ PC,R14
17750;STRNEB R0,[mem,R1]
17760MOV R2,#pagetable
17770LDRB R2,[R2,R1,LSR#12]
17780STRB R0,[R1,R2,LSL#12]
17790MOV PC,R14
17800
17810.acccon
17820]
17830IF NOTmaster THEN [OPTp:MOV PC,R14:]
17840[OPTp
17850LDRB R1,[mem,#ACCCON]
17860STRB R0,[mem,#ACCCON]
17870EOR R2,R0,R1
17880
17890TST R2,#%1 ; main/shadow to be displayed
17900STRNEB R2,[mem,#tamper]
17910
17920MOV R12,#pagetable
17930
17940
17950;TST R2,#%100 ; main/shadow to be paged in
17960;;;;;BNE swap_main_shadow
17970;MOVEQ R13,#&A0
17980;MOVNE R13,#&8D
17990;STRB R13,[R12,#3]
18000;STRB R13,[R12,#4]
18010;STRB R13,[R12,#5]
18020;STRB R13,[R12,#6]
18030;STRB R13,[R12,#7]
18040
18050
18060.swap_exit
18070
18080;ANDS R2,R2,#%1000 ; filing system RAM
18090
18100TST R0,#%1000
18110MOVEQ R13,#&A0
18120MOVNE R13,#&95-&C
18130STRB R13,[R12,#&C]
18140STRB R13,[R12,#&D]
18150MOV PC,R14
18160
18170
18180MOVEQ PC,R14
18190
18200STMFD mem,{R0-R2,R4-R9,R14}
18210
18220TST R1,#%1000
18230BEQ os_out
18240;BNE os_in
18250
18260.os_in ; RJW
18270LDR R12,roms_addr
18280ADD R12,R12,#16*16*1024 ; 17th ROM = OS3.2
18290MOV R13,#&2000
18300SUB R2,mem,#&B000
18310ADD mem,mem,#&C000
18320.os_in_loop
18330LDMIA mem, {R0,R1,R4,R5,R6,R7,R8,R9}
18340STMIA R2!, {R0,R1,R4,R5,R6,R7,R8,R9}
18350LDMIA R12!,{R0,R1,R4,R5,R6,R7,R8,R9}
18360STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R9}
18370SUBS R13,R13,#4*8
18380BGT os_in_loop
18390SUB mem,mem,#&E000
18400LDMEA mem,{R0-R2,R4-R9,PC}
18410
18420.os_out ; RJW
18430MOV R13,#&2000
18440SUB R2,mem,#&B000
18450ADD mem,mem,#&C000
18460.os_out_loop
18470LDMIA R2!,{R0,R1,R4,R5,R6,R7,R8,R9}
18480STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R9}
18490SUBS R13,R13,#4*8
18500BGT os_out_loop
18510SUB mem,mem,#&E000
18520LDMEA mem,{R0-R2,R4-R9,PC}
18530
18540.strb8000 ; greater than 8000
18550]
18560IF master THEN
18570[OPTp
18580CMP R1,#&E000
18590BGE strb_rom_ret
18600CMP R1,#&C000
18610BGE strb_rom_ret2
18620CMP R1,#&9000
18630BGE strb_rom
18640]
18650ELSE
18660[OPTp
18670CMP R1,#&C000
18680BGE strb_rom_ret
18690]
18700ENDIF
18710[OPTp
18720
18730LDRB R12,[mem,#rom]
18740TST R12,#&80
18750BEQ strb_rom ; ie not private RAM
18760
18770;STRB R0,[mem,R1]
18780MOV R2,#pagetable
18790LDRB R2,[R2,R1,LSR#12]
18800STRB R0,[R1,R2,LSL#12] ; private RAM
18810MOV PC,R14
18820
18830.strb_rom
18840SUB R12,mem,#-ROMRAM
18850LDRB R13,[mem,#rom]
18860AND R13,R13,#%1111
18870LDRB R13,[R12,R13]
18880CMP R13,#0
18890MOVNE PC,R14
18900;STREQB R0,[mem,R1]
18910MOV R2,#pagetable
18920LDRB R2,[R2,R1,LSR#12]
18930STRB R0,[R1,R2,LSL#12]
18940MOV PC,R14
18950;B strb_rom_ret
18960
18970.romsel
18980LDRB R12,[mem,#ROMSEL_ON]
18990CMP R12,#0
19000MOVNE PC,R14
19010
19020AND R0,R0,#%10001111
19030STRB R0,[mem,#rom]
19040
19050MOV R12,#pagetable
19060
19070MOV R1,R0,LSL#2 ; multiply by 4
19080ADD R1,R1,#&44 ; &4C-8
19090STRB R1,[R12,#&8]
19100STRB R1,[R12,#&9]
19110STRB R1,[R12,#&A]
19120STRB R1,[R12,#&B]
19130
19140TST R0,#%10000000
19150;MOVEQ R13,#&A0 ; this will need to change
19160MOVNE R13,#&95
19170;STRB R13,[R12,#&8]
19180STRNEB R13,[R12,#&8]
19190
19200MOV PC,R14
19210
19220LDRB R1,[mem,#rom]
19230
19240]
19250IF NOTmaster THEN
19260[OPTp
19270AND R0,R0,#%1111
19280CMP R0,R1 : MOVEQ PC,R14 ; WAR (used to) need this commented out!?!
19290B romsel_next
19300]
19310ENDIF
19320[OPTp
19330
19340AND R0,R0,#%10001111
19350
19360CMP R0,R1 : MOVEQ PC,R14 ; WAR (used to) need this commented out!?!
19370
19380;EOR R2,R0,R1
19390;ANDS R2,R2,#%10000000 ; private RAM bit
19400;BEQ romsel_next ; bit not changed
19410
19420;TST R1,#%10000000
19430;BNE private_out ; map out private RAM
19440;BEQ private_in ; map in private RAM
19450
19460
19470.romsel_next
19480LDR R12,roms_addr
19490AND R2,R0,#&F ; socket number
19500LDRB R1,[mem,#rom]
19510AND R1,R1,#&F
19520STRB R0,[mem,#rom]
19530SUB R13,mem,#-ROMRAM
19540LDRB R13,[R13,R1]
19550CMP R13,#0 ; is the bank being paged out RAM?
19560BNE romsel2
19570
19580;TST R0,#%10000000 ; private RAM mapped in?
19590;MOVEQ R13,#&8000
19600;MOVNE R13,#&9000
19610MOV R13,#&8000
19620AND R0,R0,#&F
19630
19640ADD R2,R12,R1,LSL#14
19650;ADDNE R2,R2,#&1000
19660ADD R12,R12,R0,LSL#14 ; R0*16*1024
19670;ADDNE R12,R12,#&1000
19680ADR R1,romsel_loop_temp
19690STMIA R1,{R0,R4-R8,R14}
19700ADD mem,mem,R13
19710RSB R13,R13,#&C000
19720.romsel_loop
19730LDMIA mem,{R0,R1,R4,R5,R6,R7,R8,R14}
19740STMIA R2!,{R0,R1,R4,R5,R6,R7,R8,R14}
19750LDMIA R12!,{R0,R1,R4,R5,R6,R7,R8,R14}
19760STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R14}
19770SUBS R13,R13,#4*8
19780BNE romsel_loop
19790SUB mem,mem,#&C000
19800ADR R1,romsel_loop_temp
19810LDMIA R1,{R0,R4-R8,PC}
19820.romsel_loop_temp
19830EQUD 0:EQUD 0:EQUD 0:EQUD 0
19840EQUD 0:EQUD 0:EQUD 0:EQUD 0
19850
19860.romsel_empty
19870ADD R13,R2,R2,LSL#8
19880ADD R13,R13,R13,LSL#16
19890ADD R0,mem,#&8000
19900STR R13,[R0,#0]
19910STR R13,[R0,#4]
19920STR R13,[R0,#8]
19930STR R13,[R0,#12]
19940MOV PC,R14
19950
19960.romsel2
19970
19980SUB R13,mem,#-ROMRAM
19990LDRB R13,[R13,R2]
20000CMP R13,#2 ; is the bank being paged out empty?
20010BEQ romsel_empty
20020
20030;TST R0,#%10000000 ; private RAM mapped in?
20040;MOVEQ R13,#&8000
20050;MOVNE R13,#&9000
20060MOV R13,#&8000
20070AND R0,R0,#&F
20080
20090
20100ADD R12,R12,R0,LSL#14 ; R0*16*1024
20110;ADDNE R12,R12,#&1000
20120ADD mem,mem,R13
20130RSB R13,R13,#&C000
20140ADR R1,romsel_loop_temp
20150STMIA R1,{R0,R4-R8,R14}
20160.romsel2_loop
20170LDMIA R12 !,{R0,R1,R4,R5,R6,R7,R8,R14}
20180STMIA (mem)!,{R0,R1,R4,R5,R6,R7,R8,R14}
20190;LDR R1,[R12],#4
20200;STR R1,[mem],#4 ; store byte from ROM in main memory map
20210SUBS R13,R13,#4*8
20220BNE romsel2_loop
20230SUB mem,mem,#&C000
20240ADR R1,romsel_loop_temp
20250LDMIA R1,{R0,R4-R8,PC}
20260
20270.private_in ; RJW
20280STMFD mem,{R0-R2,R4-R10}
20290LDR R2,roms_addr
20300AND R1,R1,#&F
20310ADD R2,R2,R1,LSL#14 ; R1*16*1024
20320SUB R12,mem,#&B000-&8000
20330MOV R13,#&1000
20340ADD mem,mem,#&8000
20350.priv_in_loop
20360LDMIA (mem), {R1,R4,R5,R6,R7,R8,R9,R10}
20370STMIA R2!, {R1,R4,R5,R6,R7,R8,R9,R10}
20380LDMIA R12!, {R1,R4,R5,R6,R7,R8,R9,R10}
20390STMIA (mem)!,{R1,R4,R5,R6,R7,R8,R9,R10}
20400SUBS R13,13,#4*8
20410BNE priv_in_loop
20420SUB mem,mem,#&9000
20430LDMEA mem,{R0-R2,R4-R10}
20440B romsel_next
20450
20460.private_out ; RJW
20470STMFD mem,{R0-R2,R4-R10}
20480LDR R2,roms_addr
20490LDRB R1,[mem,#rom]
20500AND R1,R0,#&F
20510ADD R2,R2,R1,LSL#14 ; R1*16*1024
20520SUB R12,mem,#&B000-&8000
20530MOV R13,#&1000
20540ADD mem,mem,#&8000
20550.priv_out_loop
20560LDMIA (mem), {R1,R4,R5,R6,R7,R8,R9,R10}
20570STMIA R12!, {R1,R4,R5,R6,R7,R8,R9,R10}
20580LDMIA R2!, {R1,R4,R5,R6,R7,R8,R9,R10}
20590STMIA (mem)!,{R1,R4,R5,R6,R7,R8,R9,R10}
20600SUBS R13,R13,#4*8
20610BNE priv_out_loop
20620SUB mem,mem,#&9000
20630LDMEA mem,{R0-R2,R4-R10}
20640B romsel_next
20650
20660.crt
20670SUB R1,mem,#512 ; sheila
20680LDRB R12,[R1,#0]
20690AND R12,R12,#%11111
20700CMP R12,#17
20710MOVHI PC,R14
20720;ADR R13,crt_regs
20730SUB R13,mem,#-crt_regs
20740LDRB R1,[R13,R12]
20750CMP R1,R0 : MOVEQ PC,R14 ; no change
20760STRB R0,[R13,R12]
20770ADD PC,PC,R12,LSL#2
20780MOV R0,R0 ; padding for pipeline
20790MOV PC,R14 ; reg 0
20800B new_horizvert ; reg 1
20810MOV PC,R14 ; reg 2
20820MOV PC,R14 ; reg 3
20830MOV PC,R14 ; reg 4
20840MOV PC,R14 ; reg 5
20850B new_horizvert ; reg 6
20860MOV PC,R14 ; reg 7
20870MOV PC,R14 ; reg 8
20880MOV PC,R14 ; reg 9
20890B cursor_start ; reg 10
20900B cursor_end ; reg 11
20910B crt12 ; reg 12
20920B crt13 ; reg 13
20930B cursor_changed ; reg 14
20940B cursor_changed ; reg 15
20950MOV PC,R14 ; reg 16
20960MOV PC,R14 ; reg 17
20970
20980
20990
21000CMP R12,#14 : CMPNE R12,#15 : MOVEQ R0,#1 : STREQ R0,[mem,#cursor_tamper]
21010CMP R12,#10 : BEQ cursor_start
21020CMP R12,#11 : BEQ cursor_end
21030CMP R12,#12 : BEQ crt12 : .crt12cont
21040CMP R12,#12
21050CMPNE R12,#13
21060CMPNE R12,#1
21070CMPNE R12,#6
21080MOVNE PC,R14
21090MOV R13,#1
21100STR R13,[mem,#tamper]
21110CMP R12,#1
21120CMPNE R12,#6
21130BEQ new_horizvert
21140;CMP R12,#13
21150;SWIEQ "6502_UpdateScreen"
21160CMP R12,#12
21170CMPNE R12,#13
21180MOVNE PC,R14
21190B recalc_wrap
21200
21210.cursor_changed
21220MOV R0,#1
21230STRB R0,[mem,#cursor_tamper]
21240MOV PC,R14
21250
21260.new_horizvert
21270MOV R13,#1
21280STR R13,[mem,#tamper]
21290SUB R12,R1,R0
21300CMP R12,#2
21310MOVLE PC,R14
21320MOV R12,#255 : STRB R12,[mem,#lastmode]
21330MOV PC,R14
21340
21350.crt12
21360CMP R0,#%0110
21370MOVLT R0,#%110
21380STRB R0,[R13,R12]
21390;B crt12cont
21400.crt13
21410
21420TST F,#1<<11
21430;]
21440;IF NOT HWScroll THEN
21450;[OPTp
21460MOVEQ R13,#1
21470STREQ R13,[mem,#tamper] ; don't want this for HW Scroll
21480BEQ recalc_wrap
21490;]
21500;ELSE
21510
21520;[OPTp
21530; HW scroll
21540LDR R12,updatepixelV
21550ADR R13,dohardware_scroll
21560CMP R12,R13
21570STRNE R13,updatepixelV
21580
21590B recalc_wrap
21600
21610.dohardware_scroll
21620; Here we do the hardware scrolling
21630STR R14,yuk
21640BL dohardwarescroll
21650BL poke_updatepixelV
21660LDR R14,yuk
21670; Then we go do the update as normal.
21680;LDR PC,dohardware_scrollV ; old contents of upV
21690LDR PC,updatepixelV
21700
21710.yuk
21720EQUD 0
21730
21740;.dohardware_scrollV
21750;EQUD 0
21760
21770.dohardwarescroll
21780FNdohardwarescroll
21790
21800;.screenwidthchanged
21810;MOV PC,R14
21820
21830.hardware_scroll_stack_space
21840]:P%+=256:O%+=256:[OPT p
21850.hardware_scroll_stack_space_top
21860]
21870
21880ENDIF
21890
21900[OPTp
21910; end of hardware scroll stuff
21920
21930.cursor_start
21940\LDRB R1,[mem,#cursor_on]
21950\CMP R1,#0:\MOVNE PC,R14
21960TST F,#1 << 10 ; cursor on?
21970MOVEQ PC,R14
21980LDRB R1,[mem,#crt_regs+11]
21990AND R1,R1,#%11111
22000AND R2,R0,#%11111
22010CMP R2,R1
22020BGT blank_cursor
22030
22040EOR R0,R0,#%100000
22050TST R0,#%1100000
22060BEQ blank_cursor
22070B define_cursor
22080
22090.cursor_end
22100\LDRB R1,[mem,#cursor_on]
22110\CMP R1,#0:\MOVNE PC,R14
22120TST F,#1 << 10 ; cursor on?
22130MOVEQ PC,R14
22140AND R1,R0,#%11111
22150LDRB R2,[mem,#crt_regs+10]
22160AND R2,R2,#%11111
22170CMP R2,R1
22180BGT blank_cursor
22190B define_cursor
22200;MOV PC,R14
22210
22220.link
22230EQUD 0
22240
22250.caps_lock
22260AND R0,R0,#%1000
22270MOV R1,R0,LSL#1
22280MOV R0,#202
22290MOV R2,#%11101111
22300SWI "OS_Byte"
22310MOV R0,#118
22320SWI "OS_Byte"
22330MOV PC,R14
22340
22350.latch
22360;ORR R0,R0,#%110000
22370;STRB R0,[mem,R1] ; no fire buttons
22380ANDS R2,R0,#%111
22390
22400;RJW
22410;CMP R2,#0
22420TSTEQ F,#1<<12 ; sound on?
22430BEQ sound_latch
22440CMP R2,#3
22450BEQ latch_keyb
22460CMP R2,#6
22470BEQ caps_lock
22480LDRB R12,[mem,#crt_regs+19]
22490CMP R2,#4
22500ANDEQ R13,R0,#%1000
22510BICEQ R12,R12,#%1
22520ORREQ R12,R12,R13,LSR#3
22530CMP R2,#5
22540ANDEQ R13,R0,#%1000
22550BICEQ R12,R12,#%10
22560ORREQ R12,R12,R13,LSR#2
22570STRB R12,[mem,#crt_regs+19]
22580
22590.recalc_wrap
22600LDRB R12,[mem,#crt_regs+19]
22610ANDS R12,R12,#%11
22620MOVNE R13,#&5800
22630MOVEQ R13,#&4000
22640CMP R12,#%10
22650MOVEQ R13,#&3000
22660CMP R12,#%01
22670MOVEQ R13,#&6000
22680
22690LDRB R12,[mem,#crt_regs+13]
22700LDRB R2,[mem,#crt_regs+12]
22710AND R2,R2,#%1111
22720ADD R12,R12,R2,LSL#8
22730
22740CMP R13,R12,LSL#3
22750MOVGT R13,R12,LSL#3
22760
22770SUB R12,mem,#512 ; sheila
22780LDRB R12,[R12,#&20]
22790
22800TST R12,#%10 ; teletext?
22810MOVNE R13,#&7C00
22820
22830;AND F,F,#&FF
22840BIC F,F,#&FF000000
22850BIC F,F,#&FF0000
22860ORR F,F,R13,LSL#16
22870;STR R13,wrap_addr
22880MOV PC,R14
22890
22900
22910.latch_keyb
22920
22930AND R2,R0,#%1000
22940STRB R2,key_write_ena
22950CMP R2,#%1000
22960MOVNE PC,R14
22970MOV R2,#0
22980STRB R2,column_counter
22990MOV PC,R14
23000
23010.printer_write
23020SWI &102
23030SWI &101
23040SWI "OS_WriteC"
23050MOV R0,#152 : MOV R1,#3
23060SWI "OS_Byte" ; check printer buffer
23070BCS printer_on
23080MOV R0,#21 : MOV R1,#3
23090SWI "OS_Byte" ; flush buffer
23100.printer_on
23110SWI &103
23120LDRB R0,[mem,#ifr2]
23130ORR R0,R0,#%10
23140STRB R0,[mem,#ifr2]
23150MOV PC,R14
23160
23170.regB_41
23180
23190SUB R12,mem,#512 ; sheila
23200LDRB R1,[R12,#&C] ; PCR
23210LDRB R2,[mem,#ifr]
23220AND R13,R1,#%1110
23230TEQ R13, #%0010
23240TEQNE R13, #%0110
23250BICEQ R2,R2,#%11
23260BICNE R2,R2,#%10
23270STRB R2,[mem,#ifr]
23280.regB_4F
23290SUB R12,mem,#512 ; sheila
23300
23310STRB R0,sound_data ; keep a copy in sound_data
23320
23330LDRB R2,[R12,#&43] ; R2=data direction
23340AND R1,R0,R2
23350;MOV R1,R0
23360ANDS R0,R1,#%01110000 : MOVNE R0,#0 : STRNEB R0,column_counter
23370;EOR R1,R1,#&FF
23380;SWI "6502_Getkeyaddr"
23390LDR R0,[mem,#key_addr]
23400LDRB R2,[R0] ; shift pressed?
23410CMP R2,#0
23420ADDNE R0,R0,#256
23430
23440AND R2,R1,#&F
23450CMP R2,#&F ; column counter disabled?
23460BEQ disable_column_counter
23470LDRB R2,column_counter
23480CMP R2,#&F
23490BEQ check_row
23500
23510;BIC R1,R1,#&80
23520LDRB R0,[R0,R1]
23530;EOR R0,R0,R1,LSR#7 ; ************
23540;EOR R0,R0,#1
23550;CMP R0,#0 : ;MOVEQ R1,#0
23560ORR R0,R1,R0,LSL#7
23570;MOV R0,R1,LSL#7
23580;MOV R0,R1
23590;ADD R0,R1,R1,LSL#7
23600
23610;MOV R0,#&81
23620;MOV R2,#&FF
23630;SWI "OS_Byte"
23640;CMP R0,#98 ; space
23650;CMP R1,#&FF
23660;MOVEQ R0,#&80
23670;MOVNE R0,#0
23680STRB R0,[R12,#&4F]
23690STRB R0,[R12,#&41]
23700MOV PC,R14
23710
23720.column_counter
23730EQUD 0
23740.key_write_ena
23750EQUD 0
23760
23770.disable_column_counter
23780STRB R2,column_counter
23790.check_row
23800AND R1,R1,#%00001111
23810MOV R13,#0
23820;SWI "6502_Getkeyaddr"
23830LDR R0,[mem,#key_addr]
23840LDRB R2,[R0] ; shift pressed?
23850CMP R2,#0
23860ADDNE R0,R0,#256
23870
23880.row_loop
23890LDRB R2,[R0,R1]
23900ORR R13,R13,R2
23910ADD R1,R1,#%10000
23920TST R1,#%1110000
23930BNE row_loop
23940ANDS R12,R13,#%1
23950LDRNEB R13,[mem,#ifr]
23960ORRNE R13,R13,R12
23970STRNEB R13,[mem,#ifr]
23980SUB R0,mem,#512 ; sheila
23990LDRB R1,[R0,#&4F]
24000BIC R1,R1,#&80
24010ORR R1,R1,R12,LSL#7
24020STRB R1,[R0,#&4F]
24030STRB R1,[R0,#&41]
24040MOV PC,R14
24050
24060.IOpodule_Write
24070AND R2,R2,#&F
24080SWI "6502_WriteSheila"
24090MOV PC,R14
24100
24110.interrupt_flags
24120LDRB R2,[mem,#ifr]
24130BIC R2,R2,R0
24140STRB R2,[mem,#ifr]
24150MOV PC,R14
24160
24170
24180.interrupt_enable
24190LDRB R1,[mem,#ier]
24200TST R0,#&80
24210BICEQ R1,R1,R0
24220ORRNE R1,R1,R0
24230ORR R1,R1,#&80 ; &81
24240STRB R1,[mem,#ier]
24250;TST time,#%1
24260;SUBNE time,time,#1
24270MOV PC,R14
24280
24290.interrupt_flags2
24300LDRB R2,[mem,#ifr2]
24310BIC R2,R2,R0
24320STRB R2,[mem,#ifr2]
24330MOV PC,R14
24340
24350
24360.interrupt_enable2
24370LDRB R1,[mem,#ier2]
24380TST R0,#&80
24390BICEQ R1,R1,R0
24400ORRNE R1,R1,R0
24410ORR R1,R1,#&80 ; &81
24420STRB R1,[mem,#ier2]
24430MOV PC,R14
24440
24450.flash
24460;LDRB R1,elite
24470;CMP R1,#0
24480;BNE skip_fe20
24490TST F,#1 << 8 ; patch on?
24500BNE skip_fe20
24510LDRB R12,[mem,#fe20]
24520AND R1,R12,#%11100
24530AND R2,R0, #%11100
24540CMP R1,R2
24550MOVNE R2,#1
24560STRNEB R2,[mem,#tamper]
24570
24580AND R1,R12,#%11100000
24590AND R2,R0, #%11100000
24600CMP R1,R2
24610MOVNE R2,#1
24620STRNEB R2,[mem,#cursor_tamper]
24630
24640.skip_fe20
24650LDRB R12,[mem,#fe20]
24660STRB R0,[mem,#fe20]
24670TST R0,#%1
24680MOVEQ R0,#9
24690MOVNE R0,#10
24700MOV R1,#0
24710SWI "OS_Byte"
24720B poke_updatepixelV ; includes MOV PC,R14
24730;MOV PC,R14
24740
24750;.fe20
24760;EQUD 0
24770
24780;.crt_regs
24790;EQUD 0
24800;EQUD 0
24810;EQUD 0
24820;EQUD 0
24830;EQUD 0
24840
24850; include the sound code here contained in the Sound library
24860FNsound_latch
24870
24880
24890FNscreen
24900
24910]
24920IF HWScroll THEN [OPTp:FNhardwarescroll:]
24930[OPTp
24940
24950
24960.FFpage
24970;SUB time,time,#1
24980MOV PC,R14
24990
25000.update_pal
25010LDRB R1,[mem,#Palette]
25020CMP R1,#0
25030MOVNE PC,R14
25040.force_update_pal
25050STR R14,[mem,#Palette+4]
25060SUB R13,mem,#-pal_regs
25070LDRB R0,[R13,#0]
25080BL do_pal
25090LDRB R0,[R13,#1]
25100BL do_pal
25110LDRB R0,[R13,#2]
25120BL do_pal
25130LDRB R0,[R13,#3]
25140BL do_pal
25150LDRB R0,[R13,#4]
25160BL do_pal
25170LDRB R0,[R13,#5]
25180BL do_pal
25190LDRB R0,[R13,#6]
25200BL do_pal
25210LDRB R0,[R13,#7]
25220BL do_pal
25230LDRB R0,[R13,#8]
25240BL do_pal
25250LDRB R0,[R13,#9]
25260BL do_pal
25270LDRB R0,[R13,#10]
25280BL do_pal
25290LDRB R0,[R13,#11]
25300BL do_pal
25310LDRB R0,[R13,#12]
25320BL do_pal
25330LDRB R0,[R13,#13]
25340BL do_pal
25350LDRB R0,[R13,#14]
25360BL do_pal
25370LDRB R0,[R13,#15]
25380BL do_pal
25390MOV R14,#0:STRB R14,[mem,#pal_tamper]
25400LDR PC,[mem,#Palette+4]
25410
25420
25430.palette
25440SUB R12,mem,#-pal_regs
25450STRB R0,[R12,R0,LSR#4]
25460
25470LDRB R1,[mem,#Palette]
25480CMP R1,#0
25490MOVNE PC,R14
25500
25510MOV R1,#255:STRB R1,[mem,#pal_tamper]
25520MOV PC,R14
25530
25540.do_pal
25550LDRB R1,[mem,#fe20]
25560TST R1,#%10
25570MOVNE PC,R14 ; mode 7
25580AND R1,R1,#%11100
25590CMP R1,#%11100 : BEQ twocolpal
25600CMP R1,#%01000 : BEQ twocolpal
25610CMP R1,#%11000 : BEQ fourcolpal
25620CMP R1,#%00100 : BEQ fourcolpal
25630
25640
25650.sixteencolpal
25660AND R1,R0,#&F
25670MOV R0,R0,LSR#4
25680EOR R1,R1,#7
25690
25700;CMP R0,#0 ; for Exile
25710;SWINE ETC ETC
25720
25730SWI &100+19
25740SWI "OS_WriteC"
25750MOV R0,R1
25760SWI "OS_WriteC"
25770SWI &100
25780SWI &100
25790SWI &100
25800MOV PC,R14
25810
25820.twocolpal
25830AND R1,R0,#&F
25840MOV R0,R0,LSR#7
25850EOR R1,R1,#7
25860CMP R0,#1
25870MOVEQ R0,#3 ; mode 4 fix
25880SWI &100+19
25890SWI "OS_WriteC"
25900MOV R0,R1
25910SWI "OS_WriteC"
25920SWI &100
25930SWI &100
25940SWI &100
25950MOV PC,R14
25960
25970.fourcolpal
25980AND R1,R0,#&F
25990AND R0,R0, #%10100000
26000TST R0, #%10000000
26010ORRNE R0,R0,#%01000000
26020BICNE R0,R0,#%10000000
26030MOV R0,R0,LSR#5
26040EOR R1,R1,#7
26050SWI &100+19
26060SWI "OS_WriteC"
26070MOV R0,R1
26080SWI "OS_WriteC"
26090SWI &100
26100SWI &100
26110SWI &100
26120MOV PC,R14
26130
26140.osbput
26150MOV R0,A,LSR#24
26160MOV R1,Y,LSR#24
26170SWI "XOS_BPut"
26180BVS swi_error
26190B opcode(&60) ; rts
26200
26210.osbget
26220MOV R0,A,LSR#24
26230MOV R1,Y,LSR#24
26240SWI "XOS_BGet"
26250BVS swi_error
26260MOV A,R0,LSL#24
26270FNsetupC
26280B opcode(&60) ; rts
26290
26300.swi_error
26310ADD mem,mem,#&100
26320ADD mem,mem,#&002
26330MOV R1,#0 ; BRK
26340STRB R1,[mem,#-2]
26350LDRB R1,[R0] ; error no
26360STRB R1,[mem,#-1]
26370ADD R0,R0,#4
26380MOV R14,#0
26390
26400.swi_err_loop
26410LDRB R13,[R0,R14]
26420CMP R13,#0
26430;MOV R13,#ASC"A"
26440STRB R13,[mem,R14]
26450ADD R14,R14,#1
26460MOVEQ R14,#255
26470CMP R14,#253
26480BLE swi_err_loop
26490
26500MOV zpc,#&100 << 16
26510SUB mem,mem,#&100
26520SUB mem,mem,#&002
26530FNfetch2
26540
26550.return_ROMSEL
26560LDRB R0,[mem,#rom]
26570MOV PC,R14
26580
26590.return_ACCCON
26600LDRB R0,[mem,#ACCCON]
26610MOV PC,R14
26620
26630
26640
26650.strb_rom_ret
26660
26670.sheila
26680SUBS R2,R1,#&FE00
26690MOVLT PC,R14
26700SUBS R2,R2,#&100
26710MOVGE PC,R14
26720;BGE FFpage
26730
26740TST time,#%1
26750SUBNE time,time,#1
26760SUBEQ time,time,#2
26770
26780;STRB R0,[mem,R1]
26790SUB R2,mem,#&10000:STRB R0,[R2,R1]
26800
26810AND R2,R1,#&FF
26820;ADR R1,sheila_writetab
26830LDR PC,[PC,R2,LSL#2]
26840EQUD 0 ; padding for pipeline
26850.sheila_writetab
26860; 0-F
26870EQUD dummy
26880EQUD crt
26890EQUD dummy
26900EQUD crt
26910EQUD dummy
26920EQUD crt
26930EQUD dummy
26940EQUD crt
26950EQUD writeFE08
26960EQUD writeFE09
26970FNequd(6,dummy)
26980; 10-17
26990EQUD writeFE10
27000FNequd(7,dummy)
27010; 18-1F
27020EQUD write_ADC_status
27030FNequd(7,dummy)
27040; 20-2F
27050EQUD flash
27060EQUD palette
27070FNequd(14,dummy)
27080; 30-3F
27090FNequd(4,romsel)
27100EQUD acccon
27110FNequd(11,romsel)
27120; 40-4F
27130EQUD latch
27140EQUD regB_41
27150EQUD dummy
27160EQUD dummy
27170EQUD writeT1low_latch
27180EQUD writeT1high_count
27190EQUD writeT1low_latch
27200EQUD writeT1high_latch
27210EQUD writeT2low_latch
27220EQUD writeT2high_count
27230EQUD dummy
27240EQUD dummy
27250EQUD dummy
27260EQUD interrupt_flags
27270EQUD interrupt_enable
27280EQUD regB_4F
27290; 50-5F
27300EQUD latch
27310EQUD regB_41
27320EQUD dummy
27330EQUD dummy
27340EQUD writeT1low_latch
27350EQUD writeT1high_count
27360EQUD writeT1low_latch
27370EQUD writeT1high_latch
27380EQUD writeT2low_latch
27390EQUD writeT2high_count
27400EQUD dummy
27410EQUD dummy
27420EQUD dummy
27430EQUD interrupt_flags
27440EQUD interrupt_enable
27450EQUD regB_4F
27460; 60-7F
27470]
27480IF IO_Podule% THEN
27490[OPTp
27500FNequd(&20,IOpodule_Write)
27510]
27520ELSE
27530[OPTp
27540EQUD dummy
27550EQUD printer_write
27560EQUD dummy
27570EQUD dummy
27580EQUD writeT3low_latch
27590EQUD writeT3high_count
27600EQUD writeT3low_latch
27610EQUD writeT3high_latch
27620EQUD writeT4low_latch
27630EQUD writeT4high_count
27640EQUD dummy
27650EQUD writeACR2
27660EQUD dummy
27670EQUD interrupt_flags2
27680EQUD interrupt_enable2
27690EQUD printer_write
27700
27710EQUD dummy
27720EQUD printer_write
27730EQUD dummy
27740EQUD dummy
27750EQUD writeT3low_latch
27760EQUD writeT3high_count
27770EQUD writeT3low_latch
27780EQUD writeT3high_latch
27790EQUD writeT4low_latch
27800EQUD writeT4high_count
27810EQUD dummy
27820EQUD dummy
27830EQUD dummy
27840EQUD interrupt_flags2
27850EQUD interrupt_enable2
27860EQUD printer_write
27870]
27880ENDIF
27890
27900[OPTp
27910; 80-BF
27920FNequd(&40,dummy)
27930; C0-CF
27940EQUD write_ADC_status
27950FNequd(15,dummy)
27960; D0-FF
27970FNequd(&30,dummy)
27980
27990.ldrb_FFpage
28000;SUB time,time,#1
28010MOV PC,R14
28020
28030.ldrb8000 ; greater than 8000
28040
28050CMP R1,#&FE00
28060BHS ldrb_sheila
28070
28080;LDRB R0,[mem,R1]
28090MOV R0,#pagetable
28100LDRB R0,[R0,R1,LSR#12]
28110LDRB R0,[R1,R0,LSL#12]
28120MOV PC,R14
28130
28140
28150;MOV R1,R1,LSR#16
28160]
28170IF master THEN
28180[OPTp
28190.ldrb16_8000 ; greater than 8000
28200
28210CMP R1,#&FE00 << 16
28220BHS ldrb16_sheila
28230
28240;LDRB R0,[mem,R1,LSR#16]
28250MOV R0,#pagetable
28260LDRB R0,[R0,R1,LSR#28]
28270MOV R0,R0,LSL#12
28280LDRB R0,[R0,R1,LSR#16]
28290
28300MOV PC,R14
28310
28320.ldrb16_screen
28330CMP R1,#&8000 << 16
28340BHS ldrb16_8000
28350
28360LDRB R12,[mem,#ACCCON]
28370
28380CMP zpc,#&C000 << 16
28390MOVLT R13,R12,LSR#1
28400MOVGE R13,R12
28410CMP zpc,#&E000 << 16
28420MOVGE R13,R12,LSR#1 ; now bit 1 of R13 is what
28430 ; we must look at
28440
28450;CMP zpc,#&C000 << 16
28460;MOVLT R13,#0
28470;EORGE R13,R12,R12,LSR#1
28480;CMP zpc,#&E000 << 16
28490;MOVGE R13,#0 ; now look at bit 1 of R13
28500
28510;TST R13,#%10
28520;SUBNE R13,mem,#(&3000+&10000) ; shadow screen memory
28530;LDRNEB R0,[R13,R1,LSR#16]
28540;LDREQB R0,[mem,R1,LSR#16]
28550;MOV PC,R14
28560
28570MOV R2,#pagetable
28580LDRB R2,[R2,R1,LSR#28]
28590TST R13,#%10
28600MOVNE R2,#&8D
28610MOV R2,R2,LSL#12
28620LDRB R0,[R2,R1,LSR#16]
28630MOV PC,R14
28640]
28650ELSE
28660[OPTp
28670.ldrb16_screen
28680CMP R1,#&FE00 << 16
28690BHS ldrb16_sheila
28700
28710LDRB R0,[mem,R1,LSR#16]
28720MOV PC,R14
28730]
28740ENDIF
28750
28760IF master THEN
28770[OPTp
28780
28790.ldrb_screen
28800.ldrb3000 ; greater than 3000
28810
28820CMP R1,#&8000
28830BHS ldrb8000
28840
28850LDRB R12,[mem,#ACCCON]
28860
28870CMP zpc,#&C000 << 16
28880MOVLT R13,R12,LSR#1
28890MOVGE R13,R12
28900CMP zpc,#&E000 << 16
28910MOVGE R13,R12,LSR#1 ; now bit 1 of R13 is what
28920 ; we must look at
28930
28940;CMP zpc,#&C000 << 16
28950;MOVLT R13,#0
28960;EORGE R13,R12,R12,LSR#1
28970;CMP zpc,#&E000 << 16
28980;MOVGE R13,#0 ; now look at bit 1 of R13
28990
29000;TST R13,#%10
29010;SUBNE R13,mem,#(&3000+&10000) ; shadow screen memory
29020;LDRNEB R0,[R13,R1]
29030;LDREQB R0,[mem,R1]
29040;MOV PC,R14
29050
29060MOV R2,#pagetable
29070LDRB R2,[R2,R1,LSR#12]
29080TST R13,#%10
29090MOVNE R2,#&8D
29100LDRB R0,[R1,R2,LSL#12]
29110MOV PC,R14
29120]
29130ELSE
29140[OPTp
29150.ldrb_screen
29160.ldrb3000 ; greater than 3000
29170CMP R1,#&FE00
29180BHS ldrb_sheila
29190LDRB R0,[mem,R1]
29200MOV PC,R14
29210]
29220ENDIF
29230
29240[OPTp
29250
29260.ldrb16_sheila
29270MOV R12,R1,LSR#16
29280B ldrb_sheila2
29290
29300.ldrb_sheila
29310MOV R12,R1
29320
29330.ldrb_sheila2
29340;LDRB R0,[mem,R12]
29350MOV R0,#pagetable
29360LDRB R0,[R0,R12,LSR#12]
29370LDRB R0,[R12,R0,LSL#12]
29380
29390SUBS R2,R12,#&FE00
29400MOVLT PC,R14
29410SUBS R2,R2,#&100
29420BGE ldrb_FFpage
29430
29440SUB R2,mem,#&10000:LDRB R0,[R2,R12]
29450
29460SUB time,time,#1
29470
29480AND R2,R12,#&FF
29490;ADR R1,sheila_readtab
29500LDR PC,[PC,R2,LSL#2]
29510EQUD 0 ; padding for pipeline
29520.sheila_readtab
29530; 0-F
29540FNequd(8,dummy)
29550EQUD readFE08
29560EQUD readFE09
29570FNequd(6,dummy)
29580; 10-2F
29590EQUD readFE10
29600FNequd(&1F,dummy)
29610; 30-3F
29620FNequd(4,return_ROMSEL)
29630FNequd(4,return_ACCCON)
29640FNequd(8,dummy)
29650; 40-4F
29660EQUD ldrb40
29670EQUD ldrb41
29680EQUD dummy
29690EQUD dummy
29700EQUD readT1low_count
29710EQUD readT1high_count
29720EQUD readT1low_latch
29730EQUD readT1high_latch
29740EQUD readT2low_count
29750EQUD readT2high_count
29760EQUD dummy
29770EQUD dummy
29780EQUD dummy
29790EQUD read_ifr
29800EQUD read_ier
29810EQUD ldrb4F
29820; 50-5F
29830EQUD ldrb40
29840EQUD ldrb41
29850EQUD dummy
29860EQUD dummy
29870EQUD readT1low_count
29880EQUD readT1high_count
29890EQUD readT1low_latch
29900EQUD readT1high_latch
29910EQUD readT2low_count
29920EQUD readT2high_count
29930EQUD dummy
29940EQUD dummy
29950EQUD dummy
29960EQUD read_ifr
29970EQUD read_ier
29980EQUD ldrb4F
29990; 60-6F
30000]
30010IF IO_Podule% THEN
30020[OPTp
30030FNequd(&20,IOpodule_Read)
30040]
30050ELSE
30060[OPTp
30070EQUD dummy
30080EQUD dummy
30090EQUD dummy
30100EQUD dummy
30110EQUD readT3low_count
30120EQUD readT3high_count
30130EQUD readT3low_latch
30140EQUD readT3high_latch
30150EQUD readT4low_count
30160EQUD readT4high_count
30170EQUD dummy
30180EQUD dummy
30190EQUD dummy
30200EQUD read_ifr2
30210EQUD read_ier2
30220EQUD dummy
30230
30240EQUD dummy
30250EQUD dummy
30260EQUD dummy
30270EQUD dummy
30280EQUD readT3low_count
30290EQUD readT3high_count
30300EQUD readT3low_latch
30310EQUD readT3high_latch
30320EQUD readT4low_count
30330EQUD readT4high_count
30340EQUD dummy
30350EQUD dummy
30360EQUD dummy
30370EQUD read_ifr2
30380EQUD read_ier2
30390EQUD dummy
30400]
30410ENDIF
30420
30430[OPTp
30440; 80-FF
30450FNequd(&80,dummy)
30460
30470FNsound_misc
30480
30490.opcode7
30500SWI &100+ASC"O"
30510SWI &100+ASC"p"
30520SWI &100+ASC"7"
30530SWI &100+ASC" "
30540FNprint(zpc)
30550B opcode7
30560
30570FNalign16 ; fit into cache better?
30580
30590FNopcodes
30600
30610.patch_screen
30620MOV PC,R14
30630.patch_pixel
30640MOV PC,R14
30650
30660.end
30670]
30680NEXT
30690OSCLI"Load <6502Em$Dir>.SRC.revtable "+STR$~(code+mode0tab)
30700OSCLI"Load <6502Em$Dir>.SRC.mode1tab "+STR$~(code+mode1tab)
30710OSCLI"Load <6502Em$Dir>.SRC.Hmode2tab "+STR$~(code+mode2tab)
30720OSCLI"Load <6502Em$Dir>.SRC.Hmode4tab "+STR$~(code+mode4tab)
30730OSCLI"Load <6502Em$Dir>.SRC.Hmode5tab "+STR$~(code+mode5tab)
30740
30750ENDPROC
30760
30770DE
30780DEFF
30790
30800
30810DEFFNldrb2(R,S)
30820IF R<>0 OR S<>1 THEN STOP
30830IF master THEN
30840[OPTp
30850CMP S,#&3000
30860;LDRLOB R,[mem,S]
30870MOVLO R,#pagetable
30880LDRLOB R,[R,S,LSR#12]
30890LDRLOB R,[S,R,LSL#12]
30900BLHS ldrb_screen
30910]
30920ELSE
30930[OPTp
30940LDRB R,[mem,S]
30950CMP S,#&FE00
30960BLHS ldrb_sheila
30970]
30980ENDIF
30990=""
31000
31010DEFFNldrb16(R,S)
31020IF R<>0 OR S<>1 THEN STOP
31030IF master THEN
31040[OPTp
31050CMP S,#&3000 << 16
31060;LDRLOB R,[mem,S,LSR#16]
31070MOVLO R,#pagetable
31080LDRLOB R,[R,S,LSR#28]
31090MOVLO R,R,LSL#12
31100LDRLOB R,[R,S,LSR#16]
31110BLHS ldrb16_screen
31120]
31130ELSE
31140[OPTp
31150LDRB R,[mem,S,LSR#16]
31160CMP S,#&FE00 << 16
31170BLHS ldrb16_sheila
31180]
31190ENDIF
31200=""
31210
31220DEFFNstrb(R,S)
31230IF R<>0 OR S<>1 THEN ERROR
31240[OPTp
31250CMP S,F,LSR#16 ; wrap_addr
31260;STRLTB R,[mem,S]
31270MOVLT R2,#pagetable
31280LDRLTB R2,[R2,S,LSR#12]
31290STRLTB R,[S,R2,LSL#12]
31300BLGE strb
31310]
31320=""
31330
31340DEFFNstrb16(R,S)
31350IF R<>0 OR S<>1 THEN ERROR
31360[OPTp
31370MOV S,S,LSR#16
31380FNstrb(R,S)
31390]
31400=""
31410
31420DEFFNshowregs
31430[OPTp
31440FNprint(zpc)
31450FNprint(A)
31460FNprint(X)
31470FNprint(Y)
31480FNprint(SP)
31490FNprint(F)
31500ADD R12,mem,#&DF00
31510LDRB R12,[R12,#&DA]
31520MOV R12,R12,LSL#24
31530FNprint2(12)
31540SWI &10A
31550;SWI "OS_NewLine"
31560]
31570=""
31580
31590DEFFNprint(R)
31600CASE R OF
31610WHEN zpc : A$=FNprint4(R)
31620WHEN F : [OPTp:MOV R2,F,LSL#24:FNprint2(2):]
31630OTHERWISE
31640A$=FNprint2(R)
31650ENDCASE
31660=""
31670
31680WHEN A : A$=FNprint2(R)
31690WHEN X : A$=FNprint2(R)
31700WHEN Y : A$=FNprint2(R)
31710WHEN SP : [OPTp:SWI &100+ASC"1":FNprint2(SP):]
31720WHEN F : A$=FNprintflags
31730ENDCASE
31740=""
31750
31760DEFFNprintflags
31770[OPTp
31780TST F,#%1<<7 : SWIEQ &100+ASC"n" : SWINE &100+ASC"N"
31790TST F,#%1<<6 : SWIEQ &100+ASC"v" : SWINE &100+ASC"V"
31800TST F,#%1<<5 : SWIEQ &100+ASC"0" : SWINE &100+ASC"1"
31810TST F,#%1<<4 : SWIEQ &100+ASC"b" : SWINE &100+ASC"B"
31820TST F,#%1<<3 : SWIEQ &100+ASC"d" : SWINE &100+ASC"D"
31830TST F,#%1<<2 : SWIEQ &100+ASC"i" : SWINE &100+ASC"I"
31840TST F,#%1<<1 : SWIEQ &100+ASC"z" : SWINE &100+ASC"Z"
31850TST F,#%1<<0 : SWIEQ &100+ASC"c" : SWINE &100+ASC"C"
31860SWI &120
31870]
31880=""
31890
31900DEFFNprint2(R)
31910LOCALI%
31920[OPTp
31930MOV R1,R
31940]
31950FORI%=0 TO 1
31960[OPT p
31970MOV R1,R1,ROR#28
31980AND R0,R1,#&F
31990CMP R0,#10
32000ADDGE R0,R0,#7
32010ADD R0,R0,#48
32020SWI "OS_WriteC"
32030]
32040NEXT
32050[OPTp
32060SWI &120
32070]
32080=""
32090
32100DEFFNprint4(R)
32110LOCALI%
32120[OPTp
32130MOV R1,R
32140]
32150FORI%=0 TO 3
32160[OPT p
32170MOV R1,R1,ROR#28
32180AND R0,R1,#&F
32190CMP R0,#10
32200ADDGE R0,R0,#7
32210ADD R0,R0,#48
32220SWI "OS_WriteC"
32230]
32240NEXT
32250[OPTp
32260SWI &120
32270]
32280=""
32290
32300DEFFNprint32(R)
32310LOCALI%
32320[OPTp
32330MOV R1,R
32340]
32350FORI%=0 TO 31
32360[OPT p
32370MOV R1,R1,ROR#28
32380AND R0,R1,#&F
32390CMP R0,#10
32400ADDGE R0,R0,#7
32410ADD R0,R0,#48
32420SWI "OS_WriteC"
32430]
32440NEXT
32450[OPTp
32460SWI &120
32470]
32480=""
32490
32500DEFFNprints(A$)
32510[OPTp
32520SWI "OS_WriteS"
32530EQUS A$
32540EQUB 10
32550EQUB 13
32560EQUB 0
32570ALIGN
32580]
32590=""
32600
32610DEFFNundoc(A%)
32620IF opcode%<>A% THEN STOP
32630[OPTp
32640;TST F,#%1000
32650;SWIEQ &100+ASC"d"
32660;SWINE &100+ASC"D"
32670
32680;SWI &100+ASC(LEFT$(RIGHT$("0"+STR$~A%,2),1))
32690;SWI &100+ASC(RIGHT$(STR$~A%,1))
32700;SWI &100+ASC" "
32710;FNprint(zpc)
32720;SWI &100+ASC" ":;SWI &100+ASC" "
32730
32740;MOV R0,#15 : ;SWI "OS_Byte"
32750;SWI 4
32760]
32770=""
32780
32790DEFFNequd(A%,B%)
32800LOCALI%
32810FORI%=1 TO A%
32820[OPTp
32830EQUD B%
32840]
32850NEXT
32860=""
32870
32880DEFFNdo_interrupt
32890[OPTp
32900MOV R0,zpc,LSR#24
32910FNpush(0)
32920MOV R0,zpc,LSR#16
32930FNpush(0)
32940BIC F,F,#%10000 ; clear BRK flag
32950FNpush(F)
32960ORR F,F,#%100 ; !!!!!!
32970MOV R0,#&FF00 : ADD R0,R0,#&FE
32980LDR zpc,[mem,R0]
32990MOV zpc,zpc,LSL#16
33000]
33010=""
33020
33030DEFFNdivmod(A,B,C,D,E)
33040div%+=1
33050[OPTp
33060MOV C,#1
33070MOV D,#0
33080MOV E,B
33090.divloop1(div%)
33100MOV B,B,LSL#1
33110MOV C,C,LSL#1
33120CMP B,A
33130BLO divloop1(div%)
33140
33150.divloop2(div%)
33160CMP B,A : BLS divjump(div%)
33170CMP B,E : BLS divjump(div%)
33180MOV B,B,LSR#1
33190MOV C,C,LSR#1
33200B divloop2(div%)
33210.divjump(div%)
33220CMP B,A
33230SUBLS A,A,B
33240ADDLS D,D,C
33250CMP B,E
33260BHI divloop2(div%)
33270]
33280=""
33290
33300DEFFNshadow
33310IF master THEN
33320[OPTp
33330LDRB R2,[mem,#ACCCON]
33340;EOR R2,R2,R2,LSR#2
33350TST R2,#%1
33360SUBNE R13,mem,#&13000
33370MOVEQ R13,mem
33380]
33390ELSE
33400[OPTp
33410MOV R13,mem
33420]
33430ENDIF
33440=""
33450DEFPROCclearmem(S%,E%)
33460P%=buffer
33470[OPT2
33480EQUD S% ; memory
33490EQUD E% ; memory+&8000
33500.clear
33510MOV R0,#0
33520LDR R1,buffer
33530LDR R2,buffer+4
33540.loop
33550STR R0,[R1],#4
33560CMP R1,R2
33570BNE loop
33580MOV PC,R14
33590]
33600CALL clear
33610ENDPROC
33620
33630DEFFNfetch2
33640[OPTp
33650;LDRB R2,[mem,zpc,LSR#16]
33660;ADD PC,table,R2,LSL#8
33670MOV R2,#pagetable
33680LDRB R2,[R2,zpc,LSR#28]
33690MOV R2,R2,LSL#12
33700LDRB R2,[R2,zpc,LSR#16]
33710ADD PC,table,R2,LSL#8
33720
33730]
33740=""
33750
33760DEFFNfetch3(N%,T%)
33770IF N%<>0 THEN [OPTp:ADD zpc,zpc,#N% << 16:]
33780[OPTp
33790FNshowregs2
33800SUBS time,time,#T%
33810;LDRPLB R2,[mem,zpc,LSR#16]
33820;ADDPL PC,table,R2,LSL#8
33830MOVPL R2,#pagetable
33840LDRPLB R2,[R2,zpc,LSR#28]
33850MOVPL R2,R2,LSL#12
33860LDRPLB R2,[R2,zpc,LSR#16]
33870ADDPL PC,table,R2,LSL#8
33880B fetch2
33890]
33900=""
33910
33920DEFFNfetch(N%,T%)
33930Q$=FNfetch3(N%,T%)
33940opcode%+=1
33950IF bcd_loop%=0 THEN
33960IF opcode(opcode%-1)=0 THEN STOP
33970IF opcode(opcode%)<>0 AND p=0 THEN STOP
33980IF P%-opcode(0)>opcode%*4*64 THEN PRINT~opcode%
33990P%=opcode(0)+opcode%*4*64
34000O%=code+P%
34010ELSE
34020P%=bcd(0)+opcode%*4*64
34030O%=code+P%
34040ENDIF
34050=""
34060DEFFNbcd(A%) :
34070IF P%>opcode(0)+(A%+256)*4*64 THEN STOP
34080P%=opcode(0)+(A%+256)*4*64 : O%=code+P% : =""
34090
34100DEFFNalign16
34110WHILE (P% AND 15)<>0
34120P%+=1 : O%+=1
34130ENDWHILE
34140=""
34150DEF PROCerror
34160REPORT:PRINT " at line ";ERL
34170END
34180
34190DEFFNshowregs2
34200[OPTp
34210;BL show_regs
34220]
34230=""
� > 6502Em
%�INPUT"Hardware scroll ";HWScroll
&�IF HWScroll<>0 THEN HWScroll=TRUE
(HWScroll=�
2master=�
<;*RMENSURE 6502Support 0.00 RMRun <6502Em$Res>.65Support
F� � �error
P
Z� V2. (master)
d
npagetable=&97000
x
�IO_Podule%=�
�
�9� opcode(&100), bcd(&100), code 500*1024, buffer 1000
�
� l%(100)
�+� divloop1(10),divloop2(10),divjump(10)
�
div%=0
� ț "<6502Em$Dir>.Src.Sound6"
�$ț "<6502Em$Dir>.Src.OpcodesNew"
�#ț "<6502Em$Dir>.Src.ScreenNew"
�"ț "<6502Em$Dir>.Src.HWScroll"
�
�electron%=�
�master=�
�PROCassemble
�PRINT(end-start)/1024
"B�OSCLI "Save <6502Em$Dir>.Code "+STR$~code+" "+STR$~(end+code)
,+�OSCLI "SetType <6502Em$Dir>.Code Data"
6
@master=�
J
�assemble
T�(end-start)/1024
^8� "Save <6502Em$Dir>.CodeM "+�~code+" "+�~(end+code)
h'� "SetType <6502Em$Dir>.CodeM Data"
r
|�
�
�0�"LOAD <6502Em$Dir>.OS1,2 "+�~(memory+&C000)
�2�"LOAD <6502Em$Dir>.BASICII "+�~(memory+&8000)
�
�� 12
�� init+code
�
�"BOO"
�
�!pc_store=&D9CD << 16
�
�D%=memory : � R3
�� start+code
�
�
��assemble
!�clearmem(code,code+200*1024)
&R=1000 : S=1000 : T=1000
0
:A=4
DX=5
NY=6
XF=7
bSP=8
l mem=3
v
time=9
�
zpc=10
�table=11
�
�
a=-&100+0
�
x=-&100+4
�
y=-&100+8
�f=-&100+12
�sp=-&100+16
�pc_store=-&100+20
�T1mode=-&100+24
�T2mode=-&100+25
�T3mode=-&100+26
�T4mode=-&100+27
T1=-&100+28
T1R=-&100+32
T2=-&100+36
T2R=-&100+40
*T3=-&100+44
4T3R=-&100+48
>T4=-&100+52
HT4R=-&100+56
Rscreen=-&100+60
\screenR=-&100+64
fmin=-&100+68
psound_timer=-&100+72
zifr=-&100+76
�ier=-&100+77
�ifr2=-&100+78
�ier2=-&100+79
�arc_screenstart=-&100+80
�tamper=-&100+84
�cursor_tamper=-&100+88
�ROMSEL_ON=-&100+92
�rom=-&100+96
�ROMRAM=-&100+100
�fe20=-&100+116
�tape_handle=-&100+117
�crt_regs=-&100+120
�scratch=-&100+140
pal_regs=-&100+148
Palette=-&100+164
ACCCON=-&100+172
$patch_on=-&100+176
.pal_tamper=-&100+177
8lastmode=-&100+178
Bfe10=-&100+179
Ltape_count=-&100+180
Vkey_addr=-&100+184
` screenstart_tamper=-&100+188
j"screenstart_previous=-&100+192
tspeedR=-&100+196
~
�(enD=-&100+200 : � don't go past this
�
��p=4 � 6 � 2
�
div%=0
�O%=code
�l%=0
�P%=0
�
opcode%=0
� [OPTp
�).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
2(.trace2 EQUD 0
<+.init_addr EQUD init
F7.crt_addr EQUD 0 ; was crt_regs
P1.T1_addr EQUD 0 ; was T1
Z..ifr_addr EQUD 0 ; ifr
d5.column_counter_addr EQUD column_counter
n1.ROMSEL_addr EQUD 0 ; ROMSEL
x2.Palette_addr EQUD 0 ; Palette
�5.speed_addr EQUD screen_count+4
�0.elite_addr EQUD 0 ; elite
�>.opco_addr EQUD opcode(0) ; opcodetable
�-.bcd_addr EQUD bcd(0)
�6.sheila_writetab_addr EQUD sheila_writetab
�5.sheila_readtab_addr EQUD sheila_readtab
�7.sound_vectors_addr EQUD sound_buffs_addr
�3.patch_addr EQUD patch_screen
�
�0.init ; only called once, before code called
�ADR 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
6ADD R6,R6,R0
@MOV R3,#255
J.init_loop
T;LDR R4,[R1,R3,LSL#2]
^;ADD R4,R4,R0
h;STR R4,[R1,R3,LSL#2]
r;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
�STR R4,[R5,R3,LSL#2]
�LDR R4,[R6,R3,LSL#2]
�ADD R4,R4,R0
�STR R4,[R6,R3,LSL#2]
�SUBS R3,R3,#1
�BPL init_loop
�MOV PC,R14
�
�
.start
�STMFD R13!,{R1-R12,R14}
STR R13,return_addr
STR R0,roms_addr
;LDR R0,crt_addr
&
;ADR R1,0
0;ADD R0,R0,R1
:;SWI "6502_Init"
D
NBL blank_cursor
X
b"MOV R0,#&9C00 : ADD R0,R0,#&40
lSTR R0,[mem,#screenR]
v
�SWI "6502_Getkeyaddr"
�STR 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 time,[mem,#min]
LDR A,[mem,#a]
LDR X,[mem,#x]
LDR Y,[mem,#y]
*"LDR SP,[mem,#sp] : �R SP,SP,#1
4LDR F,[mem,#f]
>LDR zpc,[mem,#pc_store]
H
RBL recalc_wrap
\LDRB R0,[mem,#patch_on]
f� R0,R0,#%11111
pBIC F,F,#&FF00
z�R F,F,R0,LSL#8
�
�;MOV time,#0
�
�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
.
8.reset_bcdflag
BADR R1,0
LTST F,#%1000
VLDREQ table,opco_addr
`LDRNE table,bcd_addr
jADD table,table,R1
tMOV PC,R14
~
�.block1
�EQUD 149 : EQUD -1
�.block2
�EQUD 0 : EQUD 0
�
�.screen_count
�
EQUD 0
�
EQUD 0
�
�
.reg_comp
�EQUD &FFEE << 16
�
.trace_on
MOV R12,#1
STRB R12,trace
MOV PC,R14
(
2.show_regs
<
F;SWI "6502_Checkkdata"
PLDR R0,[mem,#key_addr]
ZLDRB R0,[R0,#-4]
d
n
xCMP R0,#&1F ; Insert
��Q R1,#1
�STREQ R1,trace2
�
�LDRB R0,trace2
�
CMP R0,#1
�MOVNE PC,R14
�
�;LDR R0,reg_comp
�;CMP R0,zpc
�
;�Q R0,#1
�;STREQB R0,trace
�
�;ADD R12,mem,#&DF00
;LDRB R12,[R12,#&DA]
;CMP R12,#0
;�Q R12,#1
";STREQB R12,trace
,
6;LDRB R0,trace
@;CMP R0,#1
J;MOVNE PC,14
T
^
�showregs
hMOV PC,R14
r
|
.read_ifr
�LDRB R0,[mem,#ifr]
�
�LDR R1,[mem,#min]
�SUB R1,R1,time
�LDR R12,[mem,#screen]
�SUB R12,R12,R1
�CMP R12,#10
��RLT R0,R0,#%10 ; vsync
�;
�;
�; CMP zpc,#&8000 << 16
�; �RLT R0,R0,#%10 ; vsync
�
LDRB R1,[mem,#ier]
BIC R0,R0,#&80
&�S R1,R1,R0
0�RNE R0,R0,#&80
:
DMOV PC,R14
N
X
.read_ier
bLDRB R0,[mem,#ier]
l�R R0,R0,#&80
vMOV PC,R14
�
�.read_ifr2
�LDRB R0,[mem,#ifr2]
�LDRB R1,[mem,#ier2]
�BIC R0,R0,#&80
��S R1,R1,R0
��RNE R0,R0,#&80
�MOV PC,R14
�
�.read_ier2
�LDRB R0,[mem,#ier2]
��R R0,R0,#&80
�MOV PC,R14
.IOpodule_Read
� R0,R2,#&F
SWI "6502_ReadSheila"
*MOV PC,R14
4
>.ldrb41
H
RSUB R12,mem,#512 ; sheila
\LDRB R1,[R12,#&C] ; PCR
fLDRB R2,[mem,#ifr]
p� R13,R1,#%1110
zTEQ R13, #%0010
�TEQNE R13, #%0110
�BICEQ R2,R2,#%11
�BICNE R2,R2,#%10
�STRB R2,[mem,#ifr]
�
�LDRB R0,[R12,#&4F]
�MOV PC,R14
�
�.ldrb4F
�
�SUB R12,mem,#512 ; sheila
�LDRB R0,[R12,#&4F]
�MOV PC,R14
.readT4low_count
$LDRB R1,[mem,#ifr2]
.BIC R1,R1, #%00100000
8STRB R1,[mem,#ifr2]
BLDR R0,[mem,#T4]
LLDR R1,[mem,#min]
VSUB R0,R0,R1,LSL#15
`ADD R0,R0,time,LSL#15
jTST R0,#1 << 15 ; ???
tSUBNE time,time,#1
~MOV R0,R0,LSR#16
�� R0,R0,#&FF
�MOV PC,R14
�
�.readT4high_count
�LDR R0,[mem,#T4]
�LDR R1,[mem,#min]
�SUB R0,R0,R1,LSL#15
�ADD R0,R0,time,LSL#15
�TST R0,#1 << 15 ; ???
�SUBNE time,time,#1
�MOV R0,R0,LSR#24
�MOV PC,R14
.readT3low_count
LDR R1,[mem,#ifr2]
BIC R1,R1, #%1 << 6
(1STRB R1,[mem,#ifr2] ; clear T3 interrupt flag
2LDR R0,[mem,#T3]
<LDR R1,[mem,#min]
FSUB R0,R0,R1,LSL#15
PADD R0,R0,time,LSL#15
ZTST R0,#1 << 15 ; ???
dSUBNE time,time,#1
nMOV R0,R0,LSR#16
x� R0,R0,#&FF
�MOV PC,R14
�
�.readT3high_count
�LDR R0,[mem,#T3]
�LDR R1,[mem,#min]
�SUB R0,R0,R1,LSL#15
�ADD R0,R0,time,LSL#15
�TST R0,#1 << 15 ; ???
�SUBNE time,time,#1
�MOV R0,R0,LSR#24
�MOV PC,R14
�
�.readT3low_latch
LDRB R0,[mem,#T3R+2]
MOV PC,R14
".readT3high_latch
,LDRB R0,[mem,#T3R+3]
6MOV PC,R14
@
J.ACRtemp
T
EQUD 0
^
h.writeACR2
r;MOV R0,#0
|;STRB R0,[mem,#T3mode]
�SUB R0,mem,#512
�LDRB R1,[R0,#&60]
��R R1,R1,#&80
�STRB R1,[R0,#&60]
�;MOV R0,#1
�;STRB R0,ACRtemp
�MOV PC,R14
�
�.writeT3low_latch
�STRB R0,[mem,#T3R+2]
�MOV PC,R14
�
�.writeT3high_count
STRB R0,[mem,#T3R+3]
LDR R0,[mem,#T3R]
ADD R0,R0,#2 << 16
&
0+CMP R0,time,LSL#15 ; fix Exile's speech
:
DBHI skip_T3adjust
NLDRB R2,[mem,#ier2]
X
bTST R2,#%01000000
lMOVNE time,R0,LSR#15
v
�.skip_T3adjust
�LDR R1,[mem,#min]
�ADD R0,R0,R1,LSL#15
�SUB R0,R0,time,LSL#15
�STR R0,[mem,#T3]
�LDRB R1,[mem,#ifr2]
�BIC R1,R1, #%1 << 6
�1STRB R1,[mem,#ifr2] ; clear T3 interrupt flag
�;SUB R0,R0,#&D
�SUB R0,mem,#512 ; sheila
�
�
�LDRB R1,[R0,#&6B]
� R1,R1,#1<<7
�S R1,R1,#&C0
LDREQB R1,[R0,#&60]
BICEQ R1,R1,#&80
*STREQB R1,[R0,#&60]
4
>LDRB R12,[mem,#crt_regs+9]
HCMP R12,#3
R�Q PC,R14 ; fortress fudge
\
f%MOV R0,#1 : STRB R0,[mem,#T3mode]
pMOV PC,R14
z
�.writeT3high_latch
�STRB R0,[mem,#T3R+3]
�MOV PC,R14
�
�.writeT4low_latch
�STRB R0,[mem,#T4R+2]
�MOV PC,R14
�
�.writeT4high_count
�LDRB R1,[mem,#T4R+2]
�ADD R1,R1,R0,LSL#8
�MOV R1,R1,LSL#16
�LDR R0,[mem,#min]
ADD R1,R1,R0,LSL#15
SUB R1,R1,time,LSL#15
;ADD R1,R1,#2 << 16
$ADD R1,R1,#1 << 16
.STR R1,[mem,#T4]
8LDRB R1,[mem,#ifr2]
BBICS R1,R1, #%001 << 5
LSTRB R1,[mem,#ifr2]
V%MOV R0,#1 : STRB R0,[mem,#T4mode]
`MOV PC,R14
j
t.readT2low_count
~LDRB R1,[mem,#ifr]
�BIC R1,R1, #%101 << 5
�0STRB R1,[mem,#ifr] ; clear T2 interrupt flag
�LDR R0,[mem,#T2]
�LDR R1,[mem,#min]
�SUB R0,R0,R1,LSL#15
�ADD R0,R0,time,LSL#15
�TST R0,#1 << 15 ; ???
�SUBNE time,time,#1
�MOV R0,R0,LSR#16
�� R0,R0,#&FF
�MOV PC,R14
�
.readT2high_count
LDR R0,[mem,#T2]
LDR R1,[mem,#min]
SUB R0,R0,R1,LSL#15
(ADD R0,R0,time,LSL#15
2TST R0,#1 << 15 ; ???
<SUBNE time,time,#1
FMOV R0,R0,LSR#24
PMOV PC,R14
Z
d.readT1low_count
nLDRB R1,[mem,#ifr]
xBIC R1,R1, #%1 << 6
�0STRB R1,[mem,#ifr] ; clear T1 interrupt flag
�LDR R0,[mem,#T1]
�LDR R1,[mem,#min]
�SUB R0,R0,R1,LSL#15
�ADD R0,R0,time,LSL#15
�TST R0,#1 << 15 ; ???
�SUBNE time,time,#1
�MOV R0,R0,LSR#16
�� R0,R0,#&FF
�MOV PC,R14
�
�.readT1high_count
�LDR R0,[mem,#T1]
LDR R1,[mem,#min]
SUB R0,R0,R1,LSL#15
ADD R0,R0,time,LSL#15
"TST R0,#1 << 15 ; ???
,SUBNE time,time,#1
6MOV R0,R0,LSR#24
@MOV PC,R14
J
T.readT1low_latch
^LDRB R0,[mem,#T1R+2]
hMOV PC,R14
r
|.readT1high_latch
�LDRB R0,[mem,#T1R+3]
�MOV PC,R14
�
�.writeT1low_latch
�STRB R0,[mem,#T1R+2]
�MOV PC,R14
�
�.writeT1high_count
�STRB R0,[mem,#T1R+3]
�LDR R0,[mem,#T1R]
�LDR R1,[mem,#min]
�ADD R0,R0,R1,LSL#15
�SUB R0,R0,time,LSL#15
ADD R0,R0,#2 << 16
STR R0,[mem,#T1]
LDR R1,[mem,#ifr]
&BIC R1,R1, #%1 << 6
00STRB R1,[mem,#ifr] ; clear T1 interrupt flag
:SUB R0,mem,#512 ; sheila
DLDRB R1,[R0,#&40]
NBIC R1,R1,#&80
XSTRB R1,[R0,#&40]
b%MOV R0,#1 : STRB R0,[mem,#T1mode]
lMOV PC,R14
v
�.writeT1high_latch
�STRB R0,[mem,#T1R+3]
�MOV PC,R14
�
�.writeT2low_latch
�STRB R0,[mem,#T2R+2]
�MOV PC,R14
�
�.writeT2high_count
�LDRB R1,[mem,#T2R+2]
�ADD R1,R1,R0,LSL#8
�MOV R1,R1,LSL#16
�LDR R0,[mem,#min]
ADD R1,R1,R0,LSL#15
SUB R1,R1,time,LSL#15
ADD R1,R1,#2 << 16
STR R1,[mem,#T2]
*LDR R1,[mem,#ifr]
4BICS R1,R1, #%101 << 5
>0STRB R1,[mem,#ifr] ; clear T2 interrupt flag
H%MOV R0,#1 : STRB R0,[mem,#T2mode]
RMOV PC,R14
\
f;.T1mode
p;EQUD 1
z;.T2mode
�;EQUD 0
�;.T3mode
�;EQUD 1
�;.T4mode
�;EQUD 0
�;.T1
�;EQUD &1234 << 16
� ;.T1R
�;EQUD 20000 << 16
�;.T2
�;EQUD 98765 << 16
� ;.T2R
�;EQUD 255 << 16
;.T3
;EQUD 6777 << 16
;.T3R
$;EQUD 6777 << 16
.;.T4
8;EQUD 7380 << 16
B ;.T4R
L;EQUD 255 << 16
V;.screen
`
;EQUD 432
j
;.screenR
t;EQUD 40000
~ ;.min
�
;EQUD 200
�;.sound_timer
�;EQUD 0
�
�
�.keychk
�
EQUD 0
�
�.CLI
�BIC F,F,#%100
�ADD zpc,zpc,#1 << 16
�LDRB R0,keychk
CMP R0,#0
BLEQ keyboard
;BL keyboard
�fetch3(0,2)
(
2
<
F.fetch2
P
ZLDR R0,[mem,#min]
dSUB R0,R0,time
nLDR R1,[mem,#sound_timer]
xSUB 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
�
�LDR R0,[mem,#min]
�SUB R0,R0,time ; ***
LDR R1,speed
SUBS R1,R1,R0
STRGT R1,speed
"BLLE speed_control
,
6; LDR R0,[mem,#T1mode]
@; TST R0,#%1
J; BEQ skip_timer1
T
^LDR R0,[mem,#min]
hSUB R0,R0,time ; ***
rLDR R1,[mem,#T1]
|SUBS R1,R1,R0,LSL#15
�STRGT R1,[mem,#T1]
�BLLE timer1
�.skip_timer1
�
�; LDR R0,[mem,#T2mode]
�; TST R0,#%1
�; BEQ skip_timer2
�
�LDR R0,[mem,#min]
�SUB R0,R0,time ; ***
�LDR R1,[mem,#T2]
�SUBS R1,R1,R0,LSL#15
�STR R1,[mem,#T2]
BLLE timer2
.skip_timer2
&; LDR R0,[mem,#T3mode]
0; TST R0,#%1
:; BEQ skip_timer3
D
NLDR R0,[mem,#min]
XSUB R0,R0,time ; ***
bLDR R1,[mem,#T3]
lSUBS R1,R1,R0,LSL#15
vSTRGT R1,[mem,#T3]
�BLLE timer3
�.skip_timer3
�
�; LDR R0,[mem,#T4mode]
�; TST R0,#%1
�; MVNEQ R1,#0 ; -1
�; STREQ R1,T4
�; BEQ skip_timer4
�
�LDR R0,[mem,#min]
�SUB R0,R0,time ; ***
�LDR R1,[mem,#T4]
�SUBS R1,R1,R0,LSL#15
STR R1,[mem,#T4]
BLLE timer4
.skip_timer4
*LDR R0,[mem,#min]
4SUB R0,R0,time
>LDR R1,[mem,#tape_count]
HSUBS R1,R1,R0
RSTRGT R1,[mem,#tape_count]
\BLLE tape_fetch
f
pLDRB R1,[mem,#ifr]
zLDRB R2,[mem,#ifr2]
�%LDRB R12,[mem,#ier] : � R1,R1,R12
�%LDRB R12,[mem,#ier2]: � R2,R2,R12
�%;BIC R1,R1,#&80 : ;BIC R2,R2,#&80
�
�
�;LDRB R0,[mem,#ier]
�.;BIC R0,R0,#%1 ; ignore keyboard interrupt
�;�S R0,R0,R1
�;�RNE R1,R1,#&80
�;LDRB R0,[mem,#ier2]
�;�S R0,R0,R2
�;�RNE R2,R2,#&80
�
TST F,#%100
BNE skip_do_interrupt
;TST R1,#&80
$;TSTEQ R2,#&80
.�S R1,R1,#%01111111
8�EQS R2,R2,#%01111111
BBEQ skip_do_interrupt
L;CMP R13,#1
V;BNE skip_do_interrupt
`
j.do_interrupt
t�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
�LDRB R1,[mem,#T2mode]
CMP R1,#0
BEQ skipT2
LDR R1,[mem,#T2]
(;RJW
2MOVS R1,R1,LSR#15
<�Q R1,time
FCMP R1,time
PMOVLT time,R1
Z.skipT2
dLDR R1,[mem,#T3]
nMOVS R1,R1,LSR#15
x
� ; RJW
��Q R1,time
�CMP R1,time
�MOVLT time,R1
�LDRB R1,[mem,#T4mode]
�
CMP R1,#0
�BEQ skipT4
�LDR R1,[mem,#T4]
�
� ; RJW
�MOVS R1,R1,LSR#15
��Q R1,time
�CMP R1,time
MOVLT time,R1
.skipT4
;CMP time,#0 : ;�Q time,#1
"SUB time,time,#4
,STR time,[mem,#min]
6�fetch2
@
J.interrupt
T
^TST F,#%100
hMOVNE PC,R14
r
|LDRB R1,[mem,#ifr]
�LDRB R2,[mem,#ifr2]
�%LDRB R12,[mem,#ier] : � R1,R1,R12
�%LDRB R12,[mem,#ier2]: � R2,R2,R12
�
��S R1,R1,#%01111111
��EQS R2,R2,#%01111111
�
�Q PC,R14
�
��do_interrupt
�
�MOV PC,R14
�
�.F10temp
EQUD 0
.F10
&SWI "6502_Getkdata"
0STR R14,F10temp
:MOV R0,#255
DSTRB R0,[mem,#lastmode]
NBL updatescreen
XBL force_update_pal
Y
BL cursor
bLDR PC,F10temp
l
v;.fetch3
�
.keys2
�;SWI "6502_Checkkdata"
�LDR R0,[mem,#key_addr]
�LDRB R0,[R0,#-4]
�
�
�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
!MOV PC,R14
!
!*
.keyboard
!4MOV R0,#1 : STR R0,keychk
!>
!H
!R;SWI "6502_Checkkdata"
!\LDR R0,[mem,#key_addr]
!fLDRB R0,[R0,#-4]
!pCMP R0,#&FF : �Q PC,R14
!z
!�
!�SWI "6502_Getkdata"
!�;CMP R0,#&FF : ;�Q PC,R14
!�CMP 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]
"8CMP R0,#&FF
"B;BEQ not_keyboard
"L
�Q PC,R14
"V
"`;B not_keyboard
"jCMP R0,#10 ; shift, ctrl
"tMOVLT PC,R14
"~LDRB R1,[mem,#ifr]
"�-�R R1,R1,#%1 ; interrupt is from keyboard
"�STRB R1,[mem,#ifr]
"�LDRB R0,[mem,#ier]
"�TST R0,#%1
"�
�Q PC,R14
"��do_interrupt
"�MOV PC,R14
"�
"�
"�;.no_interrupt
"�;LDRB R0,trace2
"�;CMP R0,#0
# ;BEQ notrace2
#
;�showregs
#;.notrace2
#;�fetch2
#(
#2.define_cursor
#<$MOV R1,#0 : STRB R1,cursor_state
#F.define_cursor2
#PLDRB R1,cursor_state
#ZCMP R1,#0:MOVNE PC,R14
#d
#n-LDRB R1,[mem,#crt_regs+10] ; cursor start
#x
#�� R12,R1,#%100000
#�TST R12,#%1100000
#�BEQ blank_cursor
#�
#�+LDRB R2,[mem,#crt_regs+11] ; cursor end
#�� R1,R1,#31
#�� R2,R2,#31
#�
#�SUBS R12,R2,R1
#�BLT blank_cursor
#�
#�
#�LDRB R12,[mem,#fe20]
$� R12,R12,#%100000
$
$TST R12,#%1000
$"�Q R13,#2 ; mode 5
$,MOVNE R13,#1
$6
$@
MOV R0,#1
$JMOV R0,R0,LSL R13
$TTSTEQ R12,#%100000
$^�Q R0,#8 ; mode 2
$h
�Q R13,#3
$rSTRB R0,cursor_width
$|
$�TST R12,#%10 ; teletext
$�MVNNE R12,#7
$�
�Q R12,#1
$�
$�ADD R2,R2,R12
$�STRB R2,cursor_height
$�
$�;MOV R0,#1
$�;MOV R0,R0,LSL R13
$�;STRB R0,cursor_width
$�
$�
$�ADR R0,cursor_data
%SUB R0,R0,R1,LSL R13
%SUB R0,R0,R12,LSL R13
%STR R0,cursor_block+6
%&
%0MOV R0,#21
%:ADR R1,cursor_block
%DSWI "OS_Word"
%NMOVS PC,R14
%X
%b.blank_cursor
%l$MOV R1,#1 : STRB R1,cursor_state
%v.blank_cursor2
%�
%�ADR R1,cursor_block
%�ADR R0,blank_data
%�STR R0,cursor_block+6
%�MOV R0,#21
%�SWI "OS_Word"
%�MOV PC,R14
%�
%�.cursor_state
%�
EQUD 0
%�
%�.cursor_flash
%�
EQUD 0
&.flash_state
&
EQUD 0
&
& ;.not_keyboard
&*
EQUW 0
&4.cursor_block
&>
EQUB 0
&HEQUB 2 ; shape number
&R.cursor_width
&\EQUB 2 ; width in bytes
&f.cursor_height
&pEQUB 9 ; height in pixels
&z
EQUB 0
&�
EQUB 0
&�EQUD 0 ; address of data
&�
&�
&� ALIGN
&�.blank_data
&�
EQUD 0
&�
EQUD 0
&�
EQUD 0
&�
EQUD 0
&�
EQUD 0
&�
EQUD 0
&�
EQUD 0
'
EQUD 0
'
EQUD 0
'
EQUD 0
'$
EQUD 0
'.
EQUD 0
'8
EQUD 0
'B
EQUD 0
'L
EQUD 0
'V
EQUD 0
'`
EQUD 0
'j
EQUD 0
't
EQUD 0
'~
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
'�
EQUD 0
( .cursor_data
(
EQUD &FFFFFFFF
(EQUD &FFFFFFFF
(EQUD &FFFFFFFF
((EQUD &FFFFFFFF
(2EQUD &FFFFFFFF
(<EQUD &FFFFFFFF
(FEQUD &FFFFFFFF
(PEQUD &FFFFFFFF
(ZEQUD &FFFFFFFF
(dEQUD &FFFFFFFF
(nEQUD &FFFFFFFF
(xEQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
(�EQUD &FFFFFFFF
)EQUD &FFFFFFFF
)EQUD &FFFFFFFF
)EQUD &FFFFFFFF
)"EQUD &FFFFFFFF
),EQUD &FFFFFFFF
)6EQUD &FFFFFFFF
)@EQUD &FFFFFFFF
)J
)T.cursor7
)^
)hLDRB R0,[mem,#crt_regs+14]
)rLDRB R1,[mem,#crt_regs+15]
)|ADD R0,R1,R0,LSL#8
)�
)�0LDRB R1,[mem,#crt_regs+12] : ;� R1,R1,#%1111
)�LDRB R2,[mem,#crt_regs+13]
)�ADD R2,R2,R1,LSL#8
)�SUBS R0,R0,R2
)�MOVMI R0,#0
)�
)�.;LDRB R12,[mem,#crt_regs+1] ; horiz. chars
)�;MOV R12,#40
)�
)�);�divmod(0,12,1,2,13) ; R0 = R0 � R12
)�) ; R2 = R0 � R12
)�;RSB R2,R2,#25
*;MOV R2,R2,LSL#5
*;ADD R2,R2,R2,LSR#2
*;MOV R0,R0,LSL#5
*&;ADD R0,R0,R2,LSL#16
*0; We know that R0<1000
*:; R0 = R0 � 40
*D; R2 = R0 � 40
*N;�divmod(0,12,1,2,13)
*X!MOV R2,#((25<<5)+(25<<3))<<16
*bCMP R0,#640
*lSUBGE R0,R0,#640
*v$SUBGE R2,R2,#((1<<9)+(1<<7))<<16
*�CMP R0,#320
*�SUBGE R0,R0,#320
*�$SUBGE R2,R2,#((1<<8)+(1<<6))<<16
*�CMP R0,#160
*�SUBGE R0,R0,#160
*�$SUBGE R2,R2,#((1<<7)+(1<<5))<<16
*�CMP R0,#80
*�SUBGE R0,R0,#80
*�$SUBGE R2,R2,#((1<<6)+(1<<4))<<16
*�CMP R0,#40
*�SUBGE R0,R0,#40
*�$SUBGE R2,R2,#((1<<5)+(1<<3))<<16
*�
+
+ADD R0,R2,R0,LSL#5
+STR R0,osword21_5_block1
+ ADR R1,osword21_5_block
+*MOV R0,#21
+4(SWI "OS_Word" ; set pointer position
+>;MOV PC,R14
+?B define_cursor2
+H
+R;B cursor_cont
+\
+f.padding_to_align_osword
+pEQUB 0 : EQUB 0 : EQUB 0
+z.osword21_5_block
+�
EQUB 5
+�.osword21_5_block1
+�
EQUD 0
+�
+�0� R0,R0,#&20 : ADD R0,R0,#&74 : � R0,R0,#&FF
+�
+�
+�.cursor
+�+MOV R0,#0 : STR R0,[mem,#cursor_tamper]
+�
+�\LDRB R1,[mem,#cursor_on]
+�\CMP R1,#0:\MOVNE PC,R14
+�TST F,#1 << 10 ; cursor on?
,
�Q PC,R14
,
,LDRB R0,[mem,#fe20]
,$
,.TST R0,#%11100000
,8BEQ blank_cursor
,B
,LTST R0,#%10 ; teletext
,VBNE cursor7
,`
,jLDRB R0,[mem,#crt_regs+14]
,tLDRB R1,[mem,#crt_regs+15]
,~ADD R0,R1,R0,LSL#8
,�
,�/LDRB R1,[mem,#crt_regs+12] : � R1,R1,#%1111
,�LDRB R2,[mem,#crt_regs+13]
,�ADD R2,R2,R1,LSL#8
,�SUBS R0,R0,R2
,�MOVMI R0,#0
,�
,�.cursor_cont
,�
,�-LDRB R12,[mem,#crt_regs+1] ; horiz. chars
,�
,�CMP R12,#0 : �Q PC,R14
-
-
);�divmod(0,12,1,2,13) ; R0 = R0 � R12
-) ; R2 = R0 � R12
-;RSB R2,R2,#32
-(;MOV R2,R2,LSL#5
-2
-<; We know R0<32*R12
-F; R0 = R0 � R12
-P; R2 = R0 � R12
-ZMOV R2,#32<<21
-dCMP R0,R12,LSL#4
-nSUBGE R0,R0,R12,LSL#4
-xSUBGE R2,R2,#16<<21
-�CMP R0,R12,LSL#3
-�SUBGE R0,R0,R12,LSL#3
-�SUBGE R2,R2,#8<<21
-�CMP R0,R12,LSL#2
-�SUBGE R0,R0,R12,LSL#2
-�SUBGE R2,R2,#4<<21
-�CMP R0,R12,LSL#1
-�SUBGE R0,R0,R12,LSL#1
-�SUBGE R2,R2,#2<<21
-�CMP R0,R12
-�SUBGE R0,R0,R12
-�SUBGE R2,R2,#1<<21
-�
.
.9LDRB R1,[mem,#fe20] : TST R1,#%10000 : �Q R0,R0,LSL#1
.2;MOV R0,R0,LSL#4 ; these two surplus
.";ADD R0,R0,R2,LSL#16 ;
.,:ADD R0,R2,R0,LSL#4 ; this line missing in 1.30
.6STR R0,osword21_5_block1
.@ADR R1,osword21_5_block
.JMOV R0,#21
.T(SWI "OS_Word" ; set pointer position
.^;MOV PC,R14
._B define_cursor2
.h
.r.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
.�SWI "OS_ReadMonotonicTime"
.�MOV R0,R0,LSR#1
.�
CMP R0,R1
/BEQ mono_loop
/STR R0,mono_time
/
/&MOV PC,R14
/0
/:
/D
/N
.vsync
/XSTR R14,vsyncR14
/b
/l
/vLDR R0,[mem,#screenR]
/�ADD R1,R1,R0
/�STR R1,[mem,#screen]
/�
/�LDRB R0,ldrb40_tamper
/�"CMP R0,#1 : BLEQ ldrb40_update
/�
/�;BL trace_on
/�
/�;LDRB R1,screen_count
/�;SUBS R1,R1,#1
/�;LDRMIB R1,screen_count+4
/�;STRB R1,screen_count
/�LDR R0,[mem,#tamper]
0
CMP R0,#0
0
0BEQ no_tamper
0
MOV R0,#0
0*STR R0,[mem,#tamper]
04;SWI "6502_UpdateScreen"
0>BL recalc_wrap
0HBL updatescreen
0RTST F,#1 << 10 ; cursor on?
0\BLNE define_cursor
0fBLNE cursor
0p.no_tamper
0zLDRB R0,[mem,#pal_tamper]
0�
CMP R0,#0
0�BLNE update_pal
0�
0�
0�LDR R0,[mem,#cursor_tamper]
0�
CMP R0,#0
0�BLNE cursor
0�
0�
0�
0�SUB R0,mem,#512 ; sheila
0�LDRB R1,[R0,#&20]
0�TST R1,#%10 ; teletext?
1;SWINE "6502_UpdateScreen"
1BLNE updatescreen
1ADD R0,R0,#&4D
1$;LDRB R1,[R0]
1.;LDRB R2,[R0,#1]
18LDRB R1,[mem,#ifr]
1BLDRB R2,[mem,#ier]
1L+�R R1,R1,#%10 ; interrupt is from vsync
1V-TST R2,#%10 ; is vsync interrupt enabled?
1`�RNE R1,R1,#&80
1j;STRB R1,[R0]
1tSTRB R1,[mem,#ifr]
1~;BEQ no_interrupt
1�;�fetch2
1�
1�;TST F,#1 << 9
1�;BEQ skip_exact
1�
1�;LDR R1,mono_time
1�;.mono_loop
1�;SWI "OS_ReadMonotonicTime"
1�;MOV R0,R0,LSR#1
1�;CMP R0,R1
1�;BEQ mono_loop
1�;STR R0,mono_time
2
2
.skip_exact
2
2TST F,#1 << 10 ; cursor on?
2(LDREQ PC,vsyncR14
22
2<LDRB R1,cursor_state
2F
CMP R1,#0
2PLDRNE PC,vsyncR14
2Z
2dLDRB R1,[mem,#crt_regs+10]
2n/TST R1,#%1000000 ; cursor blinking enabled?
2xLDREQ PC,vsyncR14
2�
2�LDRB R0,cursor_flash
2�SUBS R0,R0,#1
2�STRB R0,cursor_flash
2�LDRGE PC,vsyncR14
2�
2�TST R1,#%100000
2�
�Q R0,#15
2�MOVNE R0,#31
2�STRB R0,cursor_flash
2�
2�LDR R14,vsyncR14
2�LDRB R0,flash_state
3� R0,R0,#1
3STRB R0,flash_state
3!CMP R0,#0 : BEQ blank_cursor2
3"B define_cursor2
3,
36;LDR PC,vsyncR14
3@
.vsyncR14
3J
EQUD 0
3T
3^.ldrb40
3h
3rLDRB R2,ldrb40_value
3|BIC R0,R0,#%110000
3��R R0,R0,R2
3�
MOV R1,#1
3�STRB R1,ldrb40_tamper
3�MOV PC,R14
3�
3�.ldrb40_update
3�MOV R0,#%110000
3�STRB R0,ldrb40_value
3�
MOV R0,#0
3�STRB R0,ldrb40_tamper
3�TST F,#1<<9 ; joystick
3�
�Q PC,R14
3�)SWI &63F40 ; "XJoystick_Read" ; joy 0
4BVS ldrb40_mouse
4� R1,R0,#&10000
4
MOV R0,#1
4&)SWI &63F40 ; "XJoystick_Read" ; joy 1
40MOVVS R0,#0
4:� R0,R0,#&10000
4DADD R1,R1,R0,LSL#1
4N� R1,R1,#&30000
4XMOV R1,R1,LSR#(16-4)
4b
4l� R2,R1,#%110000
4v
4�;ADD R13,mem,#&FE00
4�;LDRB R0,[R13,#&40]
4�;BIC R0,R0,#%110000
4�STRB R2,ldrb40_value
4�;�R R0,R0,R2
4�
4�MOV PC,R14
4�
4�.ldrb40_tamper
4�
EQUD 0
4�.ldrb40_value
4�
EQUD 0
4�
5.ldrb40_mouse
5MOV R13,R3
5SWI "OS_Mouse"
5 MOV R3,R13
5*
54MOV R2,R2,LSR#1
5>RSB R2,R2,#3
5HMOV R2,R2,LSL#4
5R;ADD R13,mem,#&FE00
5\;LDRB R0,[R13,#&40]
5f;BIC R0,R0,#%110000
5pSTRB R2,ldrb40_value
5z;�R R0,R0,R2
5�
5�MOV PC,R14
5�
5�.write_ADC_status
5�
5�TST F,#1<<9 ; joystick
5�
�Q PC,R14
5�
5�
5�BIC R12,R0,#%11110000
5�
5�MOV R0,R0,LSR#1
5�!� R0,R0,#%1 ; joystick number
6!SWI &63F40 ; "XJoystick_Read"
6BVS write_ADC_mouse
6
6$
6.(TST R12,#%1 ; left/right or up/down
68�Q R0,R0,LSR#8
6BADD R0,R0,#127
6L� R0,R0,#&FF
6VRSBEQ R0,R0,#255
6`
6jMOV R1,R0,LSR#2
6t� R1,R1,#%110000
6~�R R12,R12,R1
6��R R12,R12,#%1000000
6�
6�SUB R1,mem,#512 ; sheila
6�
6�STRB R12,[R1,#&C0]
6�STRB R12,[R1,#&18]
6�
6�STRB R0,[R1,#&C1]
6�STRB R0,[R1,#&19]
6�MOV R12,#0
6�STRB R12,[R1,#&C2]
6�STRB R12,[R1,#&1A]
7
7
MOV PC,R14
7
7.write_ADC_mouse
7(
72MOV R13,R3
7<SWI "OS_Mouse"
7FMOV R3,R13
7P
7ZMOV R2,#1024
7dSUB R2,R2,#1
7nSUBS R0,R2,R0
7xMOVLT R0,#0
7�
7�;CMP R0,#1024
7�;MOVGE R0,#1024
7�;SUBGE R0,R0,#1
7�
7�(TST R12,#%1 ; left/right or up/down
7�MOVNE R0,R1
7�
7�MOV R1,R0,LSL#4
7�� R1,R1,#%110000
7��R R12,R12,R1
7��R R12,R12,#%1000000
7�
8SUB R1,mem,#512 ; sheila
8
8STRB R12,[R1,#&C0]
8"STRB R12,[R1,#&18]
8,
86MOV R12,R0,LSR#2
8@STRB R12,[R1,#&C1]
8JSTRB R12,[R1,#&19]
8TMOV R12,R0,LSL#6
8^STRB R12,[R1,#&C2]
8hSTRB R12,[R1,#&1A]
8r
8|MOV PC,R14
8�
8�
8�.timer1
8�LDR R0,[mem,#T1R]
8�ADD R1,R1,R0
8�ADD R1,R1,#2 << 16
8�STR R1,[mem,#T1]
8�
8�SUB R0,mem,#512 ; sheila
8�
8�LDRB R1,[R0,#&4B] ; FE4B
8�TST R1,#%01000000
8��Q R2,#0
9STREQB R2,[mem,#T1mode]
9
9TST R1,#%10000000
9&LDRNEB R2,[R0,#&40] ; FE40
90�NE R2,R2,#&80
9:STRNEB R2,[R0,#&40] ; FE40
9D
9NLDRB R1,[mem,#ifr]
9X3�R R1,R1,#%01000000 ; interrupt is from timer 1
9bSTRB R1,[mem,#ifr]
9l
9vMOV PC,R14
9�
9�.timer2
9�LDRB R0,[mem,#T2mode]
9�
CMP R0,#0
9�
�Q PC,R14
9�
MOV R0,#0
9�STRB R0,[mem,#T2mode]
9�
9�LDRB R1,[mem,#ifr]
9��R R1,R1,#%00100000
9�STRB R1,[mem,#ifr]
9�
9�MOV PC,R14
:
:.timer3
:LDR R0,[mem,#T3R]
: ADD R1,R1,R0
:*STR R1,[mem,#T3]
:4
:>SUB R0,mem,#512 ; sheila
:H
:RLDRB R1,[R0,#&6B]
:\TST R1,#%01000000
:fBNE T3mode_skip2
:p
:zLDRB R1,[mem,#T3mode]
:�
CMP R1,#1
:�;SWINE &100+�"1"
:�;SWIEQ &100+�"0"
:�BNE T3mode_skip
:�
:�.T3mode_skip2
:�LDRB R1,[mem,#ifr2]
:��R R1,R1,#%01000000
:�STRB R1,[mem,#ifr2]
:�
:�
:�;LDRB R1,[R0,#&6B] ; FE6B
:�;TST R1,#%01000000
;
;�Q R2,#0
;;MOVNE R2,#1
;;STREQB R2,[mem,#T3mode]
;$;SWIEQ &100+�"z"
;.
;8.T3mode_skip
;B
MOV R2,#0
;LSTRB R2,[mem,#T3mode]
;V
;`;LDRB R1,[R0,#&6B] ; FE6B
;j;TST R1,#%10000000
;t;LDRB R2,[R0,#&60] ; FE60
;~;�NE R2,R2,#&80
;�;�REQ R2,R2,#&80
;�;STRB R2,[R0,#&60] ; FE60
;�
;�LDRB R1,[R0,#&6B] ; FE6B
;�� R1,R1,#&C0
;�TST R1,#&C0
;�LDRB R2,[R0,#&60] ; FE60
;��EQ R2,R2,#&80
;��RNE R2,R2,#&80
;�STRB R2,[R0,#&60] ; FE60
;�
;�
<