-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjh4th2ra.s
10892 lines (8662 loc) · 370 KB
/
jh4th2ra.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
@ *************** copyright J.J. Hoekstra 2017 ************** @
@ 22/Feb/17, 17:06
@
@ *********************** register model **********************{
@ r0 scratch 1
@ r1 scratch 2
@ r2 scratch 3
@ r3 scratch 4
@ r4 scratch 5
top .req r5 @ top datastack
fps .req r6 @ float stack pointer - alleen 64 bit floats!
loopi .req r7 @ loop I - J en do via userstack
looplim .req r8 @ loop limit - mn do loops en evt count down loops
dts .req r9 @ data stack pointer
uss .req r10 @ user stack pointer
@ r11 evt loop stack pointer, v helaas wel meer en meer in gebruik
v .req r11 @ second Forth working register - primitives use only
w .req r12 @ classic Forth working register - primitives use only
@ sp r13 return stack pointer
@ lr r14 return link
@ pc r15 feitelijk de instructie pointer}
@ *********************** header flags **********************{
@.set HiddenFlag, 0x00}
@ ******************* MEMORY MAP en TASKS *******************{
@ Define memory-map:
.equ NO_CACHE_MEM, 0x3A000000 @ is 16 Mb onder de 64 Mb GPU memory #DEBUG: kijken of dit beter werkt
.equ MAIL_DATA, NO_CACHE_MEM+0x0 @ YEAH!!! Dit is waar de mailboxes heen schijven
@ .set FB_INFO, NO_CACHE_MEM+0x1000 @ experimentele FrameBuffer locatie in non-cachable gebied - crasht. maar heeft gewerkt!
.equ TASK_BLOCK, 0x39000000 @ 16 Mb voor 256 tasks a maximaal 64 k data per task
.equ TEXT_BLOCK, 0x31000000 @ 8*16 = 128 Mb voor String-handling
.equ TOP_DATA, 0x31000000 @ dit is eerste plek waar niet meer kan worden geschreven!
@ Define Taskblock - vectors naar de verschillende dingen per task
.equ TaskContext, 0x0 @ 1024 bytes voor context, moet genoeg zijn
.equ TaskPad, 0x0400 @ een userpad/data voor elke task - 4092 bytes - telt omhoog!
@ hier 31744 bytes vrij voor user-variabelen voor een task
.equ TaskDTS, 0x9F00 @ 8192 bytes voor datastack (telt naar beneden)
.equ TaskUSS, 0xBF00 @ 8192 bytes voor userstack
.equ TaskFPS, 0xDF00 @ 8192 bytes voor float point stack = 1024 values
.equ TaskRTS, 0xFF00 @ 8192 bytes voor return-stack= 2048 values
.equ TaskSize, 16 @ een task neemt 2^16 bytes in taskblock in beslag - een task altijd macht 2 bytes
.equ RetSt, TASK_BLOCK+TaskRTS @ werkt - stacks van task 0 nu in TaskBlock!!
.equ DatSt, TASK_BLOCK+TaskDTS
.equ UseSt, TASK_BLOCK+TaskUSS
.equ FloSt, TASK_BLOCK+TaskFPS
@ TaskContext - vectors van de 'TaskTable'
.equ MaxTask, 128 @ aantal tasks
.equ TaskTableByte, 8 @ breedte van apart tabelletje buiten het TaskBlock
.equ TaskCoreNo, 0 @ core0=main, core1=free, core2=free, core3=sound (8 bit-regs)
.equ TaskClass, 1 @ class of task: 0=core, 1=event (ie: irq oid), 2=shared, 3=empty, 0xff=EOT (8 bit)
.equ TaskStatus, 2 @ status of task: active=0, paused=1, to-be-switched-to-core=4,5,6,7 (8 bit)
@ loop (die loopt op elke core apart): kijk of core jouw core is...
@ zo ja: check TaskClass=event, zo nee: op naar volgende taak
@ Check TaskClass: als core of shared: do corecheck of do slice-check, otherwise go to next task
@ Als een ronde zonder activatie van een taak: put taskmanager to sleep till next interrupt.
@.equ empty @ vrije byte
.equ TaskPrioCnt, 4 @ if zero: give a slice to task and reset to PrioSet-value; otherwise reduce by 1 (16 bit)
.equ TaskPrioSet, 6 @ Set value of priority: 0 = highest prio, =run at every slice (16 bit)
@ 1 run at every other slice, etc.
@ de eerste 5, meest gebruiukte, woorden van het 'TASK_BLOCK' nu in een aparte tabel (nl: 'tasktable' ) ivm. caching - staat hier direct boven
.equ TaskExToken, 16 @ 1 word => start van deze task bij new- or restart
.equ TaskWinNo, 20 @ 1 word => window waar deze task print - 0 tot max_win of -1 (ie. do not print at a window)
.equ TaskUARTen, 24 @ 1 word - true (ie. print at UART) or false (ie. do not print at UART)
.equ TaskCPUState, 28 @ 4 (?) words = 16
.equ emptyregs, 44 @ to align the next two at 64
.equ TaskSavedRgx, 64 @ 16 words = 64 bytes lang
.equ TaskSavedFpx, 128 @ 16 words = 64 bytes lang
.equ TaskFromTaskM, 192 @ 2 words - message from task-manager - (?) Bijvoorbeeld:stop zodra mogelijk
.equ TaskToTaskM, 200 @ 2 words - message to task-manager - (?) Bijvoorbeeld:
.equ TaskMessWrite, 208 @ 1 word - message write pointer van een 256 word circulaire buffer
.equ TaskMessRead, 212 @ 1 word - message read pointer
.equ TaskMessBuff, 216 @ 192 words - start message circulaire buffer van 192 words
.equ TaskDataEnd, 984 @ einde circulaire buffer en einde van Taskdata
@ checked }
@ ******************** standard tasks etc *******************{
@ dit zijn de tasks die permanent in het TaskBlock ( 'TASK_BLOCK' ) en in de 'TaskTable' zitten
.equ TaskNoCore0, 0
.equ TaskNoCore1, 1
.equ TaskNoCore2, 2
.equ TaskNoCore3, 3
.equ TaskNoPIXEL, 4
.equ TaskNoSOUND, 5
.equ TaskNoFREE, 6 @ eerste vrije veld in TaskBlock
.equ TaskNoEND, MaxTask-13 @ boven dit nummer nooit kijken door de taskmanagers - is ook laatste vrije veld
.equ TaskNoIRQ0, MaxTask-12 @ dit is de task-manager van core0 - hoofdtaskmanager
.equ TaskNoIRQ1, MaxTask-11 @ dit is de task-manager van core1 - #PIXEL
.equ TaskNoIRQ2, MaxTask-10 @ dit is de task-manager van core2
.equ TaskNoIRQ3, MaxTask-9 @ dit is de task-manager van core3 - #WAVE=sound-manager
.equ TaskNoFIQ0, MaxTask-8
.equ TaskNoFIQ1, MaxTask-7
.equ TaskNoFIQ2, MaxTask-6
.equ TaskNoFIQ3, MaxTask-5 @ dit is de sound-manager - core3 - gaat voor de task-manager
.equ TaskNoSMC0, MaxTask-4
.equ TaskNoSMC1, MaxTask-3
.equ TaskNoSMC2, MaxTask-2
.equ TaskNoSMC3, MaxTask-1
@ }
@ *************************** MACROs **************************{
.macro testhead name, link, codelen, immflag @ 64byte lange header met 64byte aligned execution-token -> spaart cache-lines
.section .rodata
.align 6 @ begin altijd ge-aligned op 64 bytes
.word \link
.byte \codelen @ Lengte Word voor Inlining, alleen voor Code
.byte \immflag @ -1:immediate, 1:normaal, 2:compile only
.byte 0x0 @ hidden tijdens definitie niet nodig -> byte nog vrij
.byte 2f-1f @ lengte van de naam van het WORD
.word 0x0 @ crc - hashtable code
.word 0x0 @ vocabulary - code (of ascii??)
.skip 16
1: .ascii "\name" @ name, gebruikt in assembler
2: .space 32-2b+1b @ zou moeten kunnen
.endm
.macro codehead name, namelen, link, codelen, immflag
@ bijv: codehead "/", 1, DROP, 0 - waarbij 'DROP' het vorige woord in de lijst is
.section .rodata
.align 2
.word \link @ link naar vorige woord -> dword
.byte \codelen @ Lengte Word voor Inlining, alleen voor Code
.byte \immflag @ -1:immediate, 1:normaal, 2:compile only
.byte 0x0 @ hidden tijdens definitie niet nodig -> byte nog vrij
.byte \namelen @ lengte van de naam van het WORD
@ plus 4 bytes vrij
.ascii "\name" @ name, gebruikt in assembler
.space 32-\namelen @ fixed space of 32 chars for name
.endm
.macro wordhead name, namelen, link, immflag
@ bijv: codehead "dup", 3, DROP, 2, 0 - waarbij DROP het vorige woord in de lijst is
.section .rodata
.align 2
.word \link @ link naar vorige woord
.byte 0 @ Lengte Word voor Inlines, alleen voor Code
@ word ook te inlinen als push en pop specifiek aangepast worden bij inlinen
.byte \immflag @ -1:immediate, 1:normaal, 2:compile only
.byte 0x0 @ hidden tijdens definitie niet nodig -> byte nog vrij
.byte \namelen @ lengte van de naam van het WORD
.ascii "\name" @ naam van woord in de assembler
.space 32-\namelen @ fixed space of 32 chars for name
.endm
@ de volgende macro, defvar, is inline-able.
@ een var is een asm-routine die een voor de variabele vast adres op stack zet
@ er lijken geen bijzondere dingen nodig voor een variabele
@ in interpreter mode kan het gewoon gecalled worden
@ in compiler kan het gewoon gecalled of ge-inlined worden
@ macro om in de assembler een variabele te definieren in de dictionary 6c - 3-4c YEAH!!!
.macro defvar asmname, dictname, dictnamelen, link, initial=0
.section .rodata
.align 2
.word \link
.byte 3 @ aantal opcodes voor inline, deze macro prima te inlinen
.byte 1 @ 1:normaal
.byte 0x0 @ hidden tijdens definitie niet nodig -> byte nog vrij
.byte \dictnamelen
.ascii "\dictname" @ naam van VARIABLE in dictionary
.space 32-\dictnamelen @ 32 lange naam, fixed length
\asmname : @ naam van VARIABLE in assembler omgeving
str top, [dts, #-4]! @ save oude top op stack
movw top, #:lower16:1f @ zet address van 1: in top
movt top, #:upper16:1f
bx lr
1: .word \initial @ dit is de initieele waarde van de variabele
@ direct na de definitie van een var kan via 'allot' extra ruimte
@ gegeven worden! Bijvoorbeeld voor string of array
.text @ dit moet na .word anders staat de data niet in dictionary
.endm
@ macro om in assembler waarde uit variabele te halen ipv: 'bl varXXX, bl FETCH, popdts' - 3-4c ipv 22c oid
.macro getvalvar myreg, varname
ldv32 \myreg, (16+\varname) @ fast way of getting value from variable defined in assembler
ldr \myreg, [\myreg] @ loads value of variable into myreg
.endm
@ macro om in assembler waarde in een variabele te zetten ipv: 'pushdts, bl varXXX, bl STORE' - 4c ipv 22c oid
.macro putvalvar myreg, scratch, varname @ clobbers both regs
ldv32 \scratch, (16+\varname) @ fast way of getting value from variable defined in assembler
str \myreg, [\scratch] @ stores value of myreg into variable
.endm
@ macro om de waarde van een variabele 1 op te hogen ipv: 'bl varXXX bl FETCH bl ONEPLUS bl varXXX bl STORE' -
.macro add1valvar scratch1, scratch2, varname @ clobbers both regs - 6c ipv 30c oid
ldv32 \scratch1, (16+\varname) @ fast way of getting value from variable defined in assembler
ldr \scratch2, [\scratch1]
add \scratch2, \scratch2, #1
str \scratch2, [\scratch1] @ stores value of myreg into variable
.endm
@ macro om een waarde in TaskOnCore0 te zetten
.macro valtocore0task value, myrega, myregb
ldv32 \myrega, TaskOnCore0
ldv16 \myregb, \value
str \myregb, [\myrega] @ zet waarde in TaskOnCore0
.endm
@ macro om een waarde in TaskOnCore1 te zetten
.macro valtocore1task value, myrega, myregb
ldv32 \myrega, TaskOnCore1
ldv16 \myregb, \value
str \myregb, [\myrega] @ zet waarde in TaskOnCore1
.endm
@ data en instructie barrier macro
.macro barrier
isb
dsb
isb
.endm
@ Kleine getallen zijn 1 opcode korter. Derde variant: als een getal past in
@ 8 bit plus 5 bit shift, dit moet nog.
@ macro om in de assembler een constante te definieren in de dictionary
.macro defcon32 asmname, dictname, dictnamelen, link, value
@ bijv: defcon HOOGTE, "hoogte", 6, <vorig woord> - wordt automatich op value gezet
.section .rodata
.align 2
.word \link
.byte 3 @ aantal opcodes voor inlining, ook voor constants dus
.byte 1 @ 1 is normaal - dus niet immediate
.byte 0x0 @ dit gaat vrij zeker een aanduiding worden van wat het is
.byte \dictnamelen
.ascii "\dictname" @ naam van CONSTANTE
.space 32-\dictnamelen @ 32 lange naam
\asmname :
str top,[dts, #-4]!
movw top, #:lower16:\value
movt top, #:upper16:\value
bx lr
.text
.endm
@ macro om in de assembler een constante te definieren in de dictionary
@ ALLEEN voor positieve 16 bits getallen!!!!
.macro defcon16 asmname, dictname, dictnamelen, link, value
@ bijv: defcon16 HOOGTE, 6, <vorig woord> - wordt automatich op value gezet
.section .rodata
.align 2
.word \link
.byte 2 @ aantal opcodes voor inline, ook voor constants dus
.byte 1 @ 1 is normaal - dus niet immediate
.byte 0x0 @ dit gaat vrij zeker een aanduiding worden van wat het is
.byte \dictnamelen
.ascii "\dictname" @ naam van 16bit CONSTANTE
.space 32-\dictnamelen @ 32 lange naam
\asmname :
str top,[dts, #-4]! @ zet oude top op stack
movw top, #:lower16:\value @ en zet value in nieuwe top
bx lr
.text
.endm
@ macro assembler strings. Niet geschikt voor Forth Interpreter
.macro defstr name, string
.align 2
\name :
.word 2f-1f
1: .ascii "\string"
2: .byte 0
.align 2
.endm
@ macro unnamed string. Voor programmas in source-code. Geeft string met count er aan vooraf
.macro mycode string
.align 2
.word 2f-1f
1: .ascii "\string"
2:
@.byte 0
.align 2
.endm
@ macro om chars te printen - MOET in woord!!! NIET in code!!
.macro prchar char
lit16 \char
bl EMIT
.endm
@ macro om chars te debug-printen - MOET in woord!!! NIET in code!!
.macro prdbchar char
getvalvar r0, varDEBUG
@bl varDEBUG
@bl FETCH
@popdts r0 @ top weer up to date
cmp r0, #0 @ als debug 0, dan geen debug printen
beq 69f
lit16 \char
bl EMIT
69:
.endm
@ maxcro om string te printen - MOET in woord!!! NIET in code!!
.macro prstr addr
lit32 \addr
bl PR_CST
.endm
@ macro om string te debug-printen - MOET in woord!!! NIET in code!!
.macro prdbstr addr
getvalvar r0, varDEBUG
@bl varDEBUG
@bl FETCH
@popdts r0 @ top weer up to date
cmp r0, #0 @ als debug 0, dan geen debug printen
beq 69f
lit32 \addr
bl PR_CST
69:
.endm
@ prolog is het begin van elk WORD
.macro prolog
STMFD r13!,{r0-r3, lr} @ r0-r1 kost niets extra en is dus standaard
.endm @ alleen lr crasht door aannames in design door mij
@ alleen r0 is 3c langzamer!! 14c ipv 11c
@ WDUMMY: r4->13c, r3->11c, r2->13.5c!, r1->11c, r0->14c!
@ WCDUMMY: r4->13c, r3->11c, r2->11c, r1->10c, r0->10c
@ next is het einde van elk WORD
.macro next
LDMFD r13!,{r0-r3, pc}
.ltorg
.text
.endm
@ prolog is het begin van elk WORD
.macro prologmax
STMFD r13!,{r0-r4, r6-r8, v, w, lr} @ r0-r1 kost niets extra en is dus standaard
.endm
@ next is het einde van elk WORD
.macro nextmax
LDMFD r13!,{r0-r4, r6-r8, v, w, pc}
.ltorg
.text
.endm
@ codenext is het einde van elke primitive
.macro codenext
@ MOV pc, lr @ deze kost 20c op RasPi 2!!
bx lr @ deze maar 4c !! 6-7 bij slow R2
.ltorg
.text
.endm
@ push register on datastack
.macro pushdts myreg
str top, [dts, #-4]! @ zet top boven op de stack, en pas dts aan
mov top, \myreg @ en zet myreg in de top
.endm
@ pop datastack into register
.macro popdts myreg
mov \myreg, top @ put top in myreg
ldr top, [dts], #4 @ update top, correct stack
.endm
@ pop 2 datastack-cells into regs -> ie 2xpopdts in one - saves 1-2 cycles as less stack-traffic
.macro poppopdts myreg1 myreg2
mov \myreg1, top @ myreg1 now filled with top of stack
ldr \myreg2, [dts], #4 @ myreg2 now filled with 1 below top of stack
ldr top, [dts], #4 @ top restored, stack ok again
.endm
@ push register on userstack (=r10)
.macro pushuss myreg
str \myreg,[uss, #-4]! @ userstack heeft geen top register
.endm
@ pop userstack (=r10) into register
.macro popuss myreg
ldr \myreg, [uss], #4 @ userstack heeft geen top register
.endm @ en is dus sneller voor tijdelijk pop/push als de datastack
@ push number onto datastack @ 2c-3c
.macro lit16 number
str top, [dts, #-4]!
movw top, #:lower16:\number
.endm
@ push number onto datastack @ 3-4c -> kennelijk soms 1c latentie in de str
.macro lit32 number
str top, [dts, #-4]! @ hier soms 1c latentie!
movw top, #:lower16:\number
movt top, #:upper16:\number
.endm
@ laad 32 bit getal in reg @ 2c
.macro ldv32 myreg value
movw \myreg, #:lower16:\value
movt \myreg, #:upper16:\value
.endm
@ laad 16 bit getal in reg @ 1c
.macro ldv16 myreg value
movw \myreg, #:lower16:\value
.endm
@ deel 1 loop
.macro loopcheck
add loopi, loopi, #1 @ verhoog loop index met 1
cmp loopi, looplim @ vergelijk lim en i
.endm
@ deel 1 plusloop
.macro plloopcheck
add loopi, loopi, top @ tel top bij index op
ldr top, [dts], #4 @ herstel top
cmp loopi, looplim @ vergelijk lim en i
.endm
@ deel 2 loop
.macro loopend
popuss loopi @ maak van J weer I als loop klaar
popuss looplim @ en zet de oude limiet weer terug
.endm
@ clean datacache!
.macro CleanDataCacheLevel0 @ clobbers r0-r3
isb
dsb
MRC p15, 1, r0, c0, c0, 0
LDR r3, =0x1ff
AND r0, r3, r0, LSR #13
MOV r1, #0
1: @ =way_loop
MOV r3, #0
2: @ =set_loop
MOV r2, r1, LSL #30
ORR r2, r3, LSL #5
MCR p15, 0, r2, c7, c6, 2
ADD r3, r3, #1
CMP r0, r3
BGT 2b
ADD r1, r1, #1
CMP r1, #4
BNE 1b
barrier
.endm
@ Clean and invalidate multilevel datacache
.macro ResetDataCache @ => clobbers 0-4, 6-8, 11, 12
dmb
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
@beq 5f @ if loc is 0, then no need to clean
mov r12, #0 @ start clean at cache level 0
1: add r2, r12, r12, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt 4f @ skip if no cache, or just i-cache
mcr p15, 2, r12, c0, c0, 0 @ select current cache level in cssr
isb
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r6, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
2: mov r8, r4 @ create working copy of max way size
3: orr r11, r12, r8, lsl r6 @ factor way and cache number into r11
orr r11, r11, r7, lsl r2 @ factor index number into r11
mcr p15, 0, r11, c7, c14, 2 @ flush & invalidate by set/way
subs r8, r8, #1 @ decrement the way
bge 3b
subs r7, r7, #1 @ decrement the index
bge 2b
4: add r12, r12, #2 @ increment cache number
cmp r3, r12
bgt 1b
5: mov r12, #0 @ switch back to cache level 0
mcr p15, 2, r12, c0, c0, 0 @ select current cache level in cssr
barrier
.endm
@ Flush multilevel datacache
.macro FlushDataCache @ => clobbers 0-4, 6-8, 11, 12
dmb
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
@beq 5f @ if loc is 0, then no need to clean
mov r12, #0 @ start clean at cache level 0
1: add r2, r12, r12, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt 4f @ skip if no cache, or just i-cache
mcr p15, 2, r12, c0, c0, 0 @ select current cache level in cssr
isb
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r6, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
2: mov r8, r4 @ create working copy of max way size
3: orr r11, r12, r8, lsl r6 @ factor way and cache number into r11
orr r11, r11, r7, lsl r2 @ factor index number into r11
mcr p15, 0, r11, c7, c10, 2 @ flush datacache by set/way
isb
subs r8, r8, #1 @ decrement the way
bge 3b
subs r7, r7, #1 @ decrement the index
bge 2b
4: add r12, r12, #2 @ increment cache number
cmp r3, r12
bgt 1b
5: mov r12, #0 @ switch back to cache level 0
mcr p15, 2, r12, c0, c0, 0 @ select current cache level in cssr
dsb
isb
.endm
@ ******************* debug macros **************************
@ macro print registers, r0 bevat output reg
.macro prntreg strvari
pushdts r0
lit32 \strvari
bl PR_CST
bl OUT32BIN
bl CR
.endm
@ debug flag - clobbers nothing!!
.macro debugflag flag addr @ put value on address
STMFD r13!,{r0-r1} @ for use in following 3 macros
ldr r0, =\flag
ldr r1, =\addr
str r0, [r1]
LDMFD r13!,{r0-r1}
.endm
.macro debugflag1 flag @ put flag on 0x3000 without changing any regs
debugflag \flag, 0x3000
.endm
.macro debugflag2 flag
debugflag \flag, 0x3004
.endm
.macro debugflag3 flag
debugflag \flag, 0x3008
.endm
.macro incrmem addr @ clobbers nothing
stmfd r13!, {r0-r1}
ldv32 r0, \addr
ldr r1, [r0]
add r1, r1, #1
str r1, [r0]
ldmfd r13!, {r0-r1}
.endm
.macro reg2mem myreg1, myreg2, addr @ myreg2 = scratch
ldv32 \myreg2, \addr
str \myreg1, [\myreg2]
.endm
@ debugflags sysinfodbvars - for use of various debug-activities - assembly can change, addresses are stable
.macro ussdepth addr @ stores depth of uss at \addr
ldv32 r0, \addr @ clobbers r0, r1
ldv32 r1, UseSt @ UseSt= #CORE0
sub r1, r1, uss @ (= UseSt) is altijd groter of gelijk aan uss
@asr r1, r1, #2 @ depth in bytes!!!
str r1, [r0]
.endm
@ ******************* einde debug macros ********************}
@ ************** constants UART en ARM clock ****************{
.set ARM_TIMER_LOD, 0x3F00B400 @ ARM timer
.set ARM_TIMER_VAL, 0x3F00B404
.set ARM_TIMER_CTL, 0x3F00B408
.set ARM_TIMER_IRQ, 0x3F00B40C
.set ARM_TIMER_RAW, 0x3F00B410
.set ARM_TIMER_MAS, 0x3F00B414
.set ARM_TIMER_REL, 0x3F00B418
.set ARM_TIMER_DIV, 0x3F00B41C
.set ARM_TIMER_CNT, 0x3F00B420
.set TIM_CLO, 0x3F003004 @ system timer low
@ zet op ARM_TIMER_CTL op 0x00F90200 geeft 250Mhz/(249(=F9)+1) = 1 Mhz precies en enabled clock (=bit 9)
@ **************** Clock en PWM for sound *******************
.set CM_BASE, 0x3F101000 @ Clock Manager base-addr
.set CM_PWMDIV, 0x3F1010A4 @ Clock Manager PWM Clock Divisor - checked
.set CM_PWMCTL, 0x3F1010A0 @ Clock Manager PWM Clock Control
.set PWM_BASE, 0x3F20C000 @ PWM base-addr
.set PWM_CTL, 0x3F20C000 @ equal to base-addr
.set PWM_RNG1, 0x3F20C010 @ PWM Channel 1 - Range
.set PWM_RNG2, 0x3F20C020 @ PWM Channel 2 - Range
.set PWM_STA, 0x3F20C004 @ PWM status-addr
.set PWM_FIF1, 0x3F20C018 @ PWM FIFO Input-addr
@ **************** constants voor de UART - SPI *************
.equ GPPUD, 0x3F200094 @ maar 1?
.equ GPPUDCLK0, 0x3F200098 @ maar 1 reg?
.equ GPCLR0, 0x3F200028
.equ GPCLR1, 0x3F20002C
.equ GPSET0, 0x3F20001C
.equ GPSET1, 0x3F200020
.equ GPFSEL0, 0x3F200000
.equ GPFSEL1, 0x3F200004
.equ GPFSEL2, 0x3F200008
.equ GPFSEL3, 0x3F20000C
.equ GPFSEL4, 0x3F200010
@GPLEV0 en 1 (GPIO Pin Level Registers)
@GPEDS (GPIO Event Detect Status Registers)
@GPREN( GPIO Rising Edge Detect Enable Registers)
@GPFEN(GPIO Falling Edge Detect Enable Registers)
@GPHEN(GPIO High Detect Enable Registers )
@GPLEN( GPIO Low Detect Enable Registers)
@GPAREN(GPIO Asynchronous rising Edge Detect Enable Registers)
@GPAFEN(GPIO Asynchronous Falling Edge Detect Enable Registers)
.equ AUX_ENABLES, 0x3F215004
.equ AUX_MU_IO_REG, 0x3F215040
.equ AUX_MU_IER_REG, 0x3F215044
.equ AUX_MU_IIR_REG, 0x3F215048
.equ AUX_MU_LCR_REG, 0x3F21504C
.equ AUX_MU_MCR_REG, 0x3F215050
.equ AUX_MU_LSR_REG, 0x3F215054
.equ AUX_MU_MSR_REG, 0x3F215058
.equ AUX_MU_SCRATCH, 0x3F21505C
.equ AUX_MU_CNTL_REG, 0x3F215060
.equ AUX_MU_STAT_REG, 0x3F215064
.equ AUX_MU_BAUD_REG, 0x3F215068
.equ AUX_SPI0_CS, 0x3F204000 @ #ERROR?! was 0x37 - nu 0x3F
.equ AUX_SPI0_FIFO, 0x3F204004
.equ AUX_SPI0_CLK, 0x3F204008
.equ AUX_SPI0_DLEN, 0x3F20400C
.equ AUX_SPI0_LTOH, 0x3F204010
.equ AUX_SPI0_DC, 0x3F204014
@ checked }
@ *************** START en BEGIN DICTIONARY *****************{
.globl _start
_start: b _ENTRY @ dit zit op 0x8000
@ ****************** BEGIN DICTIONARY ************************
codehead "startdic", 8, 0x0, 0, 0
STARTDIC: @ first link dictionary
codenext @}
@ *************** variabelen constants ***********************{
defvar varBASE, "base", 4, STARTDIC, 10 @ base van nummer conversie en printing
defvar varSTATE, "state", 5, varBASE, 0 @ state=>compiling of interpreting
defvar varTOIN, ">in", 3, varSTATE, 0 @ positie in een text-buffer waar geinterpreteerd gaat worden
defvar varHERE, "here", 4, varTOIN, FreeRam @ eerste lege address na dictionary
defvar varHEREDATA, "heredata", 8, varHERE,(TOP_DATA-4) @ zie boven voor memory-map
defvar varOLDHERE, "oldhere", 7, varHEREDATA @
defvar varLAST, "last", 4, varOLDHERE, EndDict @ lijkt geen temp LAST nodig
defvar varOUT, "out", 3, varLAST, 0 @ positie van cursor bij EMIT - niet voor windows, die hebben ieder een eigen out variabele
defvar varCHARSIN, "charsin", 7, varOUT, 0 @ number of chars recieved with RECEIVE since last reset
defcon32 conSTARTFREE, "startfree", 9, varCHARSIN, FreeRam @ waar de interne dict eindigt - om size software ed te berekenen
defcon32 conSTARTDICT, "startdict", 9, conSTARTFREE, STARTDIC
defcon32 conMYSOURCE, "mysource", 8, conSTARTDICT, MYSOURCE
defcon32 conTEXTBLOCK, "textblock", 9, conMYSOURCE, TEXT_BLOCK
defcon32 conTASKBLOCK, "taskblock", 9, conTEXTBLOCK, TASK_BLOCK
defcon32 conTASKTABLE, "tasktable", 9, conTASKBLOCK, TaskTable
defcon32 conNEWFONT, "font1", 5, conTASKTABLE, NEWFONT
defcon32 conPOSTBUS10, "postbus10", 9, conNEWFONT, postbus1_0
defvar varMAXINLINE, "maxinline", 9, conPOSTBUS10, 5 @ -1 inline alles, 0 inline niets, 1-n inline routines tot die lengte
defvar varNEXTLINE, "nextline", 8, varMAXINLINE, MYSOURCE
defvar varNEG, "neg#", 4, varNEXTLINE, 0 @ voor nummer conversie - om sign te onhouden
defvar varNOISE, "noise", 5, varNEG, 0xfff @ voor de noise emulatie
defvar varMZ, "m_z", 3, varNOISE @ voor de rando generator
defvar varMW, "m_w", 3, varMZ @ idem
defvar varDEBUG, "debug", 5, varMW, 0 @ false=geen debug, true is debug bij compileren - functions!!
@ ******************** SYSTEM INFO VARS ***********************
defcon32 conSYSINFOVARS, "sysinfovars", 11, varDEBUG, sysinfovars
defcon32 conSYSDBVARS, "sysdbvars", 9, conSYSINFOVARS, sysdbvars
defcon32 conSIVDB0, "sivdb0", 6, conSYSDBVARS, sivdb0
defcon32 conSIVDB1, "sivdb1", 6, conSIVDB0, sivdb1
defcon32 conSIVDB2, "sivdb2", 6, conSIVDB1, sivdb2
defcon32 conSIVDB3, "sivdb3", 6, conSIVDB2, sivdb3
defcon32 conSIVC0INIT, "sivc0init", 9, conSIVDB3, sivc0init
defcon32 conSIVISC0SCTLR, "sivisc0sctlr", 12, conSIVC0INIT, sivisc0SCTLR
defcon32 conSIVISC0CPSR, "sivisc0cpsr", 11, conSIVISC0SCTLR, sivisc0CPSR
defcon32 conSIVISC0SPSRHYP, "sivisc0spsrhyp", 14, conSIVISC0CPSR, sivisc0SPSRhyp
defcon32 conSIVISC0ELRHYP, "sivisc0elrhyp", 13, conSIVISC0SPSRHYP, sivisc0ELRhyp
defcon32 conSIVISC0R13PRE, "sivisc0r13pre", 13, conSIVISC0ELRHYP, sivisc0R13pre
defcon32 conSIVISC0R14PRE, "sivisc0r14pre", 13, conSIVISC0R13PRE, sivisc0R14pre
defcon32 conSIVISC0R15PRE, "sivisc0r15pre", 13, conSIVISC0R14PRE, sivisc0R15pre
defcon32 conSIVISC0R13PST, "sivisc0r13pst", 13, conSIVISC0R15PRE, sivisc0R13pst
defcon32 conSIVISC0R14PST, "sivisc0r14pst", 13, conSIVISC0R13PST, sivisc0R14pst
defcon32 conSIVISC0R15PST, "sivisc0r15pst", 13, conSIVISC0R14PST, sivisc0R15pst
defcon32 conSIVISC0CPACR, "sivisc0cpacr", 12, conSIVISC0R15PST, sivisc0CPACR
defcon32 conSIVISC0ACTLRNS, "sivisc0actlrns", 14, conSIVISC0CPACR, sivisc0ACTLRns
defcon32 conSIVISC0CNTKCTL, "sivisc0cntkctl", 14, conSIVISC0ACTLRNS, sivisc0CNTKCTL
defcon32 conSIVENC0R13S0, "sivenc0r13s0", 12, conSIVISC0CNTKCTL, sivenc0R13s0
defcon32 conSIVENC0R14S0, "sivenc0r14s0", 12, conSIVENC0R13S0, sivenc0R14s0
defcon32 conSIVENC1R13S0, "sivenc1r13s0", 12, conSIVENC0R14S0, sivenc1R13s0
defcon32 conSIVENC1R14S0, "sivenc1r14s0", 12, conSIVENC1R13S0, sivenc1R14s0
defcon32 conSIVENC2R13S0, "sivenc2r13s0", 12, conSIVENC1R14S0, sivenc2R13s0
defcon32 conSIVENC2R14S0, "sivenc2r14s0", 12, conSIVENC2R13S0, sivenc2R14s0
defcon32 conSIVC0R0, "sivc0r0", 7, conSIVENC2R14S0, sivc0R0
defcon32 conSIVC1R0, "sivc1r0", 7, conSIVC0R0, sivc1R0
defcon32 conSIVC2R0, "sivc2r0", 7, conSIVC1R0, sivc2R0
defcon32 conSIVC3R0, "sivc3r0", 7, conSIVC2R0, sivc3R0
@ *********************** WAVE STUFF ************************
defcon32 conWVCOUNTER, "wvcounter", 9, conSIVC3R0, wvcounter
defcon32 conWVCMPWMCTL, "wvcmpwmctl", 10, conWVCOUNTER, wvcmpwmctl
@ *********************** PIXEL STUFF ***********************
defvar varSCRPITCH, "scrpitch", 8, conWVCMPWMCTL, 0 @ pitch of screen and win0
defvar varSCRSIZE, "scrsize", 7, varSCRPITCH, 0 @ size in bytes of screen
defvar varSCRBASE, "scrbase", 7, varSCRSIZE, 0 @ start van scherm geheugen waar geschreven wordt, wisselt 30 Hz
defvar varSCROFFSET, "scroffset", 9, varSCRBASE, 0 @ offset van het scherm - voor switchen van scherm
defvar varSCR0BASE, "scr0base", 8, varSCROFFSET, 0 @ vaste pointer naar nul scherm, wordt eenmalig gezet
defvar varSCRVISIBLE, "scrvisible", 10, varSCR0BASE, 1 @ welk van de 2 screens visible is - start met 0
defvar varCANVAS, "canvas", 6, varSCRVISIBLE, 0x004040 @ default background is vd cyan
defvar varINK, "ink", 3, varCANVAS, 0xf0f0f0 @ default ink=offwit
defcon32 conPXWOBASE, "pxwobase", 8, varINK, pxwobase @ address van pxwo-lijstje - obsolete
defcon32 conPXCOUNTER, "pxcounter", 9, conPXWOBASE, pxcounter @ counter die IRQ activatiobs van core1 telt
defvar varSCRY, "scry", 4, conPXCOUNTER, 0 @ cursor y-positie screen - tussen 0 en winhiy kan getekend worden
defvar varSCRX, "scrx", 4, varSCRY, 0 @ cursor x-positie screen - tussen 0 en winhix kan getekend worden
defvar varWINCURY, "wincury", 7, varSCRX, 0 @ cursor y-positie write-on window - 0,0 is 0,0 origin plus rand
defvar varWINCURX, "wincurx", 7, varWINCURY, 0 @ cursor x-positie write-on window
defvar varWINPITCH, "winpitch", 8, varWINCURX, 0 @ pitch write-on window = pitch buffer
defvar varWINSIZEX, "winsizex", 8, varWINPITCH, 0 @ size x write-on window - rand zit hier dus ook in!
defvar varWINSIZEY, "winsizey", 8, varWINSIZEX, 0 @ size y write-on window - rand zit hier dus ook in!
defvar varWINHIX, "winhix", 6, varWINSIZEY, 0 @ is winsizex-2*rand - (winlowx=altijd 0)
defvar varWINHIY, "winhiy", 6, varWINHIX, 0 @ is winsizey-2*rand - (winlowy=altijd 0)
defcon32 conWINTABLE, "wintable", 8, varWINHIY, WinTable @ plek waar windows-tabel staat
defcon32 conFBINFO, "fbinfo", 6, conWINTABLE, FB_INFO @ plek waar GPU Frame buffer dat heen schijft
defcon32 conWINMAX, "winmax", 6, conFBINFO, max_win @ maximaal aantal windows in WinTable - tussen 1 en max_win
defcon32 conWINBYTES, "winbytes", 8, conWINMAX, bytes_win @ aantal bytes per regel in WinTable
defvar varWRITEON, "writeon", 7, conWINBYTES, 0 @ window waar op getekend wordt - altijd tussen 0 en win#-1
defvar varWINNO, "win#", 4, varWRITEON, 1 @ actueel aantal windows in WinTable, nooit lager als 1!
@ 16bit:5bitRed-6bitGreen-5bitBlue
defcon32 conBLACK, "black", 5, varWINNO, 0x000000 @ 32bit:ARGB - Alpha werkt nog niet - komt ook niet...
defcon32 conWHITE, "white", 5, conBLACK, 0xf0f0f0
defcon32 conGRAY, "gray", 4, conWHITE, 0x808080
defcon32 conDGRAY, "dgray", 5, conGRAY, 0x2A3430
defcon32 conVDGRAY, "vdgray", 6, conDGRAY, 0x162016
defcon32 conLGRAY, "lgray", 5, conVDGRAY, 0xB0B3B3
defcon32 conVLGRAY, "vlgray", 6, conLGRAY, 0xc4D0D0
defcon32 conRED, "red", 3, conVLGRAY, 0xf00000
defcon32 conDRED, "dred", 4, conRED, 0x360000
defcon32 conVDRED, "vdred", 5, conDRED, 0x200000
defcon32 conLRED, "lred", 4, conVDRED, 0xf08585
defcon32 conVLRED, "vlred", 5, conLRED, 0xf0c0c8
defcon32 conBLUE, "blue", 4, conVLRED, 0x0000f0 @ very nice color
defcon32 conDBLUE, "dblue", 5, conBLUE, 0x030660 @ very nice color
defcon32 conVDBLUE, "vdblue", 6, conDBLUE, 0x000030 @ very nice color
defcon32 conLBLUE, "lblue", 5, conVDBLUE, 0x0890F0 @ very nice color 0x0080FF
defcon32 conVLBLUE, "vlblue", 6, conLBLUE, 0x08D0F0 @ very nice color
defcon32 conGREEN, "green", 5, conVLBLUE, 0x02f004 @
defcon32 conDGREEN, "dgreen", 6, conGREEN, 0x025004 @
defcon32 conVDGREEN, "vdgreen", 7, conDGREEN, 0x003000 @
defcon32 conLGREEN, "lgreen", 6, conVDGREEN, 0x40E83A @
defcon32 conVLGREEN, "vlgreen", 7, conLGREEN, 0xA0F098 @ ok
defcon32 conYELLOW, "yellow", 6, conVLGREEN, 0xf0f000 @
defcon32 conDYELLOW, "dyellow", 7, conYELLOW, 0x505000
defcon32 conVDYELLOW, "vdyellow", 8, conDYELLOW, 0x303000 @
defcon32 conLYELLOW, "lyellow", 7, conVDYELLOW, 0xf0f080
defcon32 conVLYELLOW, "vlyellow", 8, conLYELLOW, 0xf0f0d0
defcon32 conCYAN, "cyan", 4, conVLYELLOW, 0x00f0f0
defcon32 conDCYAN, "dcyan", 5, conCYAN, 0x009090 @ blauwgrijzig
defcon32 conVDCYAN, "vdcyan", 6, conDCYAN, 0x004040 @ very nice color
defcon32 conLCYAN, "lcyan", 5, conVDCYAN, 0x60f0f0
defcon32 conVLCYAN, "vlcyan", 6, conLCYAN, 0xa0f0f0
defcon32 conMAGENTA, "magenta", 7, conVLCYAN, 0xf000f0
defcon32 conDMAGENTA, "dmagenta", 8, conMAGENTA, 0x360036
defcon32 conVDMAGENTA, "vdmagenta", 9, conDMAGENTA, 0x200020
defcon32 conLMAGENTA, "lmagenta", 8, conVDMAGENTA, 0xf080f0
defcon32 conVLMAGENTA, "vlmagenta", 9, conLMAGENTA, 0xf0C0f0
@defvar varCURX, "curx", 4, conVLMAGENTA, 0 @ gehele scherm -> straks obsoleet want dit gaat via win0
@defvar varCURY, "cury", 4, varCURX, 0 @ gehele scherm -> straks obsoleet want dit gaat via win0
defcon32 conNEOFORTH, "neoforth", 8, conMAGENTA, MyNeoForth
@ checked }
@ ******************* strings 4 printing ********************{
defstr presskey, " Press ANY key..."
defstr myforth1, " === CrayOnForth ============="
defstr myforth2, " === Copyright J.J. Hoekstra ="
defstr myforth3, " === 2017 Leeuwarden ========="
defstr unknown1, " ABORT! \""
defstr unknown2, "\" unknown"
defstr immstr, "imm xt: "
defstr ordinary, "ord xt: "
defstr literal, "lit no: "
defstr debugfl1, " debugfl 1 : "
defstr debugfl2, " debugfl 2 : "
defstr debugfl3, " debugfl 3 : "
defstr stackempty, "empty"
defstr stack, "stack: "
defstr charstyped, "chars received"
defstr goreset, " > REBOOT..."
defstr redefined1, "warning: "
defstr redefined2, " redefined"
defstr nextstring, "addr next string: 0x"
defstr backfromimm, " <bckimm>"
defstr backfromnor, " <bcknor>"
defstr clearingsource, "<resetting source>"
defstr dotibio, " <tibio> "
defstr carriage, "_"
defstr pcis, "pc=0x"
defstr spis, "sp=0x"
defstr dtsis, "dts=0x"
defstr ussis, "uss=0x"
defstr fpsis, "fps=0x"
defstr lris, "lr=0x"
defstr sizedict, "===== forth-dict bytes: "
defstr sizeprog, "====== user-dict bytes: "
defstr noword, "=== defs in dictionary: "
defstr bytesfree, "=========== BYTES FREE: "
@defstr sizeword, "====== opcodes per def: "
defstr sizebanner, "------------------------------"
defstr fbinit, "framebuffer initiated..."
@ }
@ *********************** START SYSTEM **********************{
codehead "entry", 5, conNEOFORTH, 0, 1 @ traditioneel CPU setup - maar geen perifere hardware à la UART of io
_ENTRY: @{
@bl INITUART @ #DEBUG - INITUART nodig als voor _COLD debug data geprint moet worden, anders niet
reg2mem r13, r1, sivenc0R13s0 @ here the value of sp from the bootloader is visible
reg2mem r14, r1, sivenc0R14s0
ldv32 r13, 0x1000000 @ tijdelijke stackpointer #DEBUG: om te kijken of dit wat doet vwb booten-> nee!
bl INITSYS @ setup van system modus ed. - hier switch van hyp via supervisor naar system
reg2mem r13, r1, sivenc0R13s1
reg2mem r14, r1, sivenc0R14s1
incrmem sivc0init
bl INITMMU @ eerst systeem, dan memory.
reg2mem r13, r1, sivenc0R13s2
reg2mem r14, r1, sivenc0R14s2
incrmem sivc0init
bl CLEARTASKBLOCK @ clear het taskblock om zeker te zijn dat alles nul is.
reg2mem r13, r1, sivenc0R13s3
reg2mem r14, r1, sivenc0R14s3
incrmem sivc0init
bl INITTASKBLOCK @ kan evt ook voor MMU, daar MMU de caches toch reset. Deze eerste keer voor INITCORES!
reg2mem r13, r1, sivenc0R13s4
reg2mem r14, r1, sivenc0R14s4
incrmem sivc0init
bl INITTASKTABLE @ dit maar een keer voor alle cores
reg2mem r13, r1, sivenc0R13s5
reg2mem r14, r1, sivenc0R14s5
incrmem sivc0init
bl INITCORES @ start, initieert en pauseert dan cores 1-3 (reactivatie via sev)
reg2mem r13, r1, sivenc0R13s6
reg2mem r14, r1, sivenc0R14s6
incrmem sivc0init
bl INITSCREEN @ zet de buffers van win0 - eenmalig want alloceert buffer geheugen
reg2mem r13, r1, sivenc0R13s7
reg2mem r14, r1, sivenc0R14s7
incrmem sivc0init
lit16 848 @ 704*528=ok 768*576=ok 720*540=ok 800*600=ok 640*480=werkt niet op onze tv!
lit16 480 @ hoogte intern altijd meervoud van 8 -> daardoor soms meer geheugen voor scherm
bl SETWINZERO @ setup win0 en zet initieel scherm in GPU - kan (nog) niet herhaald worden
incrmem sivc0init
cpsie ifa @ start de interrupts na INITTASKBLOCK, TASKTABLE en SETWINZERO
incrmem sivc0init
b _COLD
codenext @}
@ _COLD is een restart zonder de computer te resetten
@ oa uservariabelen voor een multi-user omgeving
@ en reset van hardware en dergelijke. UART en MCS zijn goed hier.
codehead "cold", 4, _ENTRY, 0, 1
_COLD: bl INITUART @ COLD is herstart van systeem zonder systeem aan en uit te doen{
incrmem sivc0init
@bl INITWAVE @ #nadenken: geen idee of dit hier een goed idee is>
@incrmem sivc0init
bl INITMCS @ init ARM clock
incrmem sivc0init
bl INITTRNG @ init true random generator
incrmem sivc0init
bl INITPIXEL @ (her)start de interrupt van het pixel systeem
incrmem sivc0init @ init core0 in geeft 16 steps
bl BANNER @ moet in ieder geval na SETWINZERO #checked
bl CR
b _ABORT
codenext @ geen codenext nodig want ingang van COLD is een b en geen bl - maar wel voor .text!!}
@ _ABORT is voor als een programma of compilatie afbreekt door een fout
codehead "abort", 5, _COLD, 0, 1 @ maw alle FORTH-systeem variabelen en stacks resetten{
_ABORT:
@ldv32 sp, RetSt @ crash niet meer - geen idee waarom...
sev @ start core1-core3 als die slapen
isb @ wachten tot sev klaar is
bl INITTASKBLOCK
@bl INITCORES @ #UPDATE - het kan zijn dat het beter is dat de CORES1-3 gewoon doorlopen
@ voor langlopende taken. #NADENKEN
bl INITRNDM @ nu nog met vaste waarde, dat wordt straks met _MCS of zoiets
@bl CLEARTIB @ dit zet ook >in op 0
@prstr presskey
@bl ANYKEY
b _QUIT
codenext @ checked }
@}
@ _QUIT is de standard loop van de interpreter, _QUIT is een
@ eindeloze loop en reset de data en user stacks NIET!
@ maar wel de return stack (van core 0!) - WAAROM? #CHECK
codehead "quit", 4, _ABORT, 0, 1
_QUIT: @ lees input van user into input buffer
@ interpret input in input buffer
@ print ok als interpret succesvol
@ldr sp, =RetSt @ start van QUIT reset de return stack - want??
lit16 0x0
bl varTOIN @ addr van >in op stack
bl STORE @ zet 0 in >in
bl CLEARSOURCE
@ ************************************************************
@meethang:
@hang:
bl PROK
@meethang:
@bl ANYKEY
@bl TEST10M
@bl SPACE
@b meethang
hang: bl TIBIO @ nu address te lezen regel of 0 op stack
cmp top, #0x0
beq 1f @ klaar met deze source
bl DOTDBTBIO @ debug printing bij interpretatie
bl FILLTIB @ fill TIB met de regel uit source van het addres op stack