-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsokobanbios.mms
1480 lines (1200 loc) · 31.6 KB
/
sokobanbios.mms
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
% this is a reduced MMIX BIOS for the Sokoban Game
% it is considert to be in ROM mapped
% at physical address 0000 0000 0000 0000
% used with
% virtual address 8000 0000 0000 0000
% Definition of Constants
% Physical Addresses and Interrupt Numbers of Devices
PREFIX :RAM:
HI IS #8000
MH IS #0001
PREFIX :VRAM:
HI IS #8002
PREFIX :IO:
HI IS #8001
Keyboard IS #00
Screen IS #08
Mouse IS #10
GPU IS #20
Timer IS #60
PREFIX :Interrupt:
Keyboard IS 40
Screen IS 41
Mouse IS 42
GPU IS 43
Timer IS 44
Button IS Timer Same interrupt for debugging.
% Code
.section .text,"ax",@progbits
LOC #8000000000000000
PREFIX :Boot:
count IS $254
tmp IS $0
% page table setup (see small model in address.howto)
:Main IS @ dummy %Main, to keep mmixal happy
:Boot GETA tmp,:DTrap %set dynamic- and forced-trap handler
PUT :rTT,tmp
GETA tmp,:FTrap
PUT :rT,tmp
PUT :rG,254 % count zu einem globalen Register machen
PUSHJ tmp,:memory %initialize the memory setup
GET tmp,:rQ
PUT :rQ,0 %clear interrupts
% here we start a loaded user program
% rXX should be #FB0000FF = UNSAVE $255
% rBB is coppied to $255, it should be the place in the stack
% where UNSAVE will find its data
% rWW should be the entry point in the main program,
% thats where the program
% continues after the UNSAVE.
% If no program is loaded, rXX will be 0, that is TRAP 0,Halt,0
% and we end the program before it has started in the Trap handler.
NEG $255,1 % enable interrupt $255->rK with resume 1
RESUME 1 % loading a file sets up special registers for that
% Dynamic Trap Handling
PREFIX :DTrap:
:DTrap PUSHJ $255,Handler
PUT :rJ,$255
NEG $255,1 % enable interrupt $255->rK with resume 1
RESUME 1
tmp IS $0
ibits IS $1
inumber IS $2
base IS $3
Handler GET ibits,:rQ
SUBU tmp,ibits,1 %from xxx...xxx1000 to xxx...xxx0111
SADD inumber,tmp,ibits %position of lowest bit
ANDN tmp,ibits,tmp %the lowest bit
ANDN tmp,ibits,tmp %delete lowest bit
PUT :rQ,tmp %and return to rQ
SLU tmp,inumber,2 %scale
GETA base,Table %and jump
GO tmp,base,tmp
Table JMP PowerFail %0 the machine bits
JMP MemParityError %1
JMP MemNonExiistent %2
JMP Unhandled %3
JMP Reboot %4
JMP Unhandled %5
JMP PageTableError %6
JMP Intervall %7
JMP Unhandled %8
JMP Unhandled %9
JMP Unhandled %10
JMP Unhandled %11
JMP Unhandled %12
JMP Unhandled %13
JMP Unhandled %14
JMP Unhandled %15
JMP Unhandled %16
JMP Unhandled %17
JMP Unhandled %18
JMP Unhandled %19
JMP Unhandled %20
JMP Unhandled %21
JMP Unhandled %22
JMP Unhandled %23
JMP Unhandled %24
JMP Unhandled %25
JMP Unhandled %26
JMP Unhandled %27
JMP Unhandled %28
JMP Unhandled %29
JMP Unhandled %30
JMP Unhandled %31
JMP Privileged %32 % Program bits
JMP Security %33
JMP RuleBreak %34
JMP KernelOnly %35
JMP TanslationBypass %36
JMP NoExec %37
JMP NoWrite %38
JMP NoRead %39
JMP Ignore %40 formerly registered: Keyboard
JMP Screen %41
JMP Mouse %42
JMP GPU %43
JMP TCount %44
JMP Unhandled %45
JMP Unhandled %46
JMP Unhandled %47
JMP Unhandled %48
JMP Unhandled %49
JMP Unhandled %50
JMP Unhandled %51
JMP Mouse %52
JMP GPU %53
JMP Unhandled %54
JMP Unhandled %55
JMP Unhandled %56
JMP Unhandled %57
JMP Unhandled %58
JMP Unhandled %59
JMP Unhandled %60
JMP Unhandled %61
JMP Unhandled %62
JMP Unhandled %63
JMP Ignore %64 rQ was zero
% Default Dynamic Trap Handlers
Unhandled GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Trap unhandled",0
Ignore POP 0,0
% Required Dynamic Trap Handlers
Reboot GETA tmp,1F
SWYM tmp,5 % tell the debugger
JMP :Boot
1H BYTE "DEBUG Rebooting",0
MemParityError GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Memory parity error",0
MemNonExiistent GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Access to nonexistent Memory",0
PowerFail GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Power Fail - switching to battery ;-)",0
PageTableError GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Error in page table structure",0
Intervall GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Intervall Counter rI is zero",0
Privileged GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Privileged Instruction",0
Security GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Security violation",0
RuleBreak GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Illegal Instruction",0
KernelOnly GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Instruction for kernel use only",0
TanslationBypass GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Illegal access to negative address",0
NoExec GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Missing execute permission",0
NoWrite GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Missing write permission",0
NoRead GETA tmp,1F
SWYM tmp,5 % tell the debugger
POP 0,0
1H BYTE "DEBUG Missing read permission",0
% Devicespecific Dynamic Trap Handlers
PREFIX Keyboard:
base IS $1
data IS $2
count IS $3
return IS $4
tmp IS $5
% echo a character from the keyboard
:DTrap:Keyboard SETH base,:IO:HI
LDO data,base,:IO:Keyboard % keyboard status/data
BN data,1F
SR count,data,32
AND count,count,#FF
BZ count,1F
GET return,:rJ
AND tmp+1,data,#FF
PUSHJ tmp,:ScreenC
PUT :rJ,return
1H POP 0,0
:DTrap:Screen IS :DTrap:Ignore
:DTrap:Mouse IS :DTrap:Ignore
:DTrap:GPU IS :DTrap:Ignore
PREFIX :Timer:
tiOffset IS #10
counter IS $0
base IS $1
offset IS $2
:DTrap:TCount SET offset,tiOffset
LDO counter,:Boot:count
SUB counter,counter,1
STO counter,:Boot:count
BNP counter,finish
POP 0,0
finish SETH base,:IO:HI
ADD offset,offset,:IO:Timer
STCO 0,base,offset % Interrupts des Timers verhindern
POP 0,0
% Forced Trap Handling
PREFIX :FTrap:
% Entry point for a forced TRAP
:FTrap PUSHJ $255,Handler
PUT :rJ,$255
NEG $255,1 %enable interrupt $255->rK with resume 1
RESUME 1
tmp IS $0
instr IS $1
Y IS $2
Handler GET instr,:rXX
BNN instr,1F
SRU tmp,instr,24
AND tmp,tmp,#FF %the opcode
BZ tmp,Trap
1H POP 0,0 %not a TRAP or ropcode>=0
% Handle a TRAP Instruction
Trap SRU Y,instr,8
AND Y,Y,#FF %the Y value (the function code)
GETA tmp,Table
SL Y,Y,2
GO tmp,tmp,Y %Jump into the Trap Table
Table JMP Halt %0
JMP Fopen %1
JMP Fclose %2
JMP Fread %3
JMP Fgets %4
JMP Fgetws %5
JMP Fwrite %6
JMP Fputs %7
JMP Fputws %8
JMP Fseek %9
JMP Ftell %a
JMP Unhandled %b
JMP Unhandled %c
JMP Unhandled %d
JMP Unhandled %e
JMP Idle %f
JMP TWait %10
JMP TDate %11
JMP TTimeOfDay %12
JMP TCount %13
JMP TInitTimer %14
JMP Unhandled %15
JMP Unhandled %16
JMP Unhandled %17
JMP Unhandled %18
JMP Unhandled %19
JMP Unhandled %1a
JMP Unhandled %1b
JMP Unhandled %1c
JMP Unhandled %1d
JMP Unhandled %1e
JMP Unhandled %1f
JMP VPut %20
JMP VGet %21
JMP GSize %22
JMP GSetWH %23
JMP GSetPos %24
JMP GSetTextColor %25
JMP GSetFillColor %26
JMP GSetLineColor %27
JMP GPutPixel %28
JMP GPutChar %29
JMP GPutStr %2A
JMP GLine %2B
JMP GRectangle %2C
JMP GBitBlt %2D
JMP GBitBltIn %2E
JMP GBitBltOut %2F
JMP MWait %30
JMP Unhandled %31
JMP Unhandled %32
JMP Unhandled %33
JMP Unhandled %34
JMP Unhandled %35
JMP Unhandled %36
JMP Unhandled %37
JMP KGet %38
JMP KStatus %39
JMP KWait %3a
JMP Unhandled %3b
JMP Unhandled %3c
JMP Unhandled %3d
JMP Unhandled %3e
JMP Unhandled %3f
JMP Unhandled %40
JMP Unhandled %41
JMP Unhandled %42
JMP Unhandled %43
JMP Unhandled %44
JMP Unhandled %45
JMP Unhandled %46
JMP Unhandled %47
JMP Unhandled %48
JMP Unhandled %49
JMP Unhandled %4a
JMP Unhandled %4b
JMP Unhandled %4c
JMP Unhandled %4d
JMP Unhandled %4e
JMP Unhandled %4f
JMP Unhandled %50
JMP Unhandled %51
JMP Unhandled %52
JMP Unhandled %53
JMP Unhandled %54
JMP Unhandled %55
JMP Unhandled %56
JMP Unhandled %57
JMP Unhandled %58
JMP Unhandled %59
JMP Unhandled %5a
JMP Unhandled %5b
JMP Unhandled %5c
JMP Unhandled %5d
JMP Unhandled %5e
JMP Unhandled %5f
JMP Unhandled %60
JMP Unhandled %61
JMP Unhandled %62
JMP Unhandled %63
JMP Unhandled %64
JMP Unhandled %65
JMP Unhandled %66
JMP Unhandled %67
JMP Unhandled %68
JMP Unhandled %69
JMP Unhandled %6a
JMP Unhandled %6b
JMP Unhandled %6c
JMP Unhandled %6d
JMP Unhandled %6e
JMP Unhandled %6f
JMP Unhandled %70
JMP Unhandled %71
JMP Unhandled %72
JMP Unhandled %73
JMP Unhandled %74
JMP Unhandled %75
JMP Unhandled %76
JMP Unhandled %77
JMP Unhandled %78
JMP Unhandled %79
JMP Unhandled %7a
JMP Unhandled %7b
JMP Unhandled %7c
JMP Unhandled %7d
JMP Unhandled %7e
JMP Unhandled %7f
JMP Unhandled %80
JMP Unhandled %81
JMP Unhandled %82
JMP Unhandled %83
JMP Unhandled %84
JMP Unhandled %85
JMP Unhandled %86
JMP Unhandled %87
JMP Unhandled %88
JMP Unhandled %89
JMP Unhandled %8a
JMP Unhandled %8b
JMP Unhandled %8c
JMP Unhandled %8d
JMP Unhandled %8e
JMP Unhandled %8f
JMP Unhandled %90
JMP Unhandled %91
JMP Unhandled %92
JMP Unhandled %93
JMP Unhandled %94
JMP Unhandled %95
JMP Unhandled %96
JMP Unhandled %97
JMP Unhandled %98
JMP Unhandled %99
JMP Unhandled %9a
JMP Unhandled %9b
JMP Unhandled %9c
JMP Unhandled %9d
JMP Unhandled %9e
JMP Unhandled %9f
JMP Unhandled %a0
JMP Unhandled %a1
JMP Unhandled %a2
JMP Unhandled %a3
JMP Unhandled %a4
JMP Unhandled %a5
JMP Unhandled %a6
JMP Unhandled %a7
JMP Unhandled %a8
JMP Unhandled %a9
JMP Unhandled %aa
JMP Unhandled %ab
JMP Unhandled %ac
JMP Unhandled %ad
JMP Unhandled %ae
JMP Unhandled %af
JMP Unhandled %b0
JMP Unhandled %b1
JMP Unhandled %b2
JMP Unhandled %b3
JMP Unhandled %b4
JMP Unhandled %b5
JMP Unhandled %b6
JMP Unhandled %b7
JMP Unhandled %b8
JMP Unhandled %b9
JMP Unhandled %ba
JMP Unhandled %bb
JMP Unhandled %bc
JMP Unhandled %bd
JMP Unhandled %be
JMP Unhandled %bf
JMP Unhandled %c0
JMP Unhandled %c1
JMP Unhandled %c2
JMP Unhandled %c3
JMP Unhandled %c4
JMP Unhandled %c5
JMP Unhandled %c6
JMP Unhandled %c7
JMP Unhandled %c8
JMP Unhandled %c9
JMP Unhandled %ca
JMP Unhandled %cb
JMP Unhandled %cc
JMP Unhandled %cd
JMP Unhandled %ce
JMP Unhandled %cf
JMP Unhandled %d0
JMP Unhandled %d1
JMP Unhandled %d2
JMP Unhandled %d3
JMP Unhandled %d4
JMP Unhandled %d5
JMP Unhandled %d6
JMP Unhandled %d7
JMP Unhandled %d8
JMP Unhandled %d9
JMP Unhandled %da
JMP Unhandled %db
JMP Unhandled %dc
JMP Unhandled %dd
JMP Unhandled %de
JMP Unhandled %df
JMP Unhandled %e0
JMP Unhandled %e1
JMP Unhandled %e2
JMP Unhandled %e3
JMP Unhandled %e4
JMP Unhandled %e5
JMP Unhandled %e6
JMP Unhandled %e7
JMP Unhandled %e8
JMP Unhandled %e9
JMP Unhandled %ea
JMP Unhandled %eb
JMP Unhandled %ec
JMP Unhandled %ed
JMP Unhandled %ee
JMP Unhandled %ef
JMP Unhandled %f0
JMP Unhandled %f1
JMP Unhandled %f2
JMP Unhandled %f3
JMP Unhandled %f4
JMP Unhandled %f5
JMP Unhandled %f6
JMP Unhandled %f7
JMP Unhandled %f8
JMP Unhandled %f9
JMP Unhandled %fa
JMP Unhandled %fb
JMP Unhandled %fc
JMP Unhandled %fd
JMP Unhandled %fe
JMP Unhandled %ff
% Default TRAP Handlers
Unhandled GETA tmp,1F
SWYM tmp,5 % inform the debugger
NEG tmp,1
PUT :rBB,tmp %return -1
POP 0,0
1H BYTE "DEBUG Unhandled TRAP",0
Halt GETA tmp,1F
SWYM tmp,5 % inform the debugger
9H SYNC 4 % go to power save mode
GET tmp,:rQ
BZ tmp,9B
PUSHJ tmp,:DTrap:Handler
JMP 9B % and loop idle
1H BYTE "DEBUG Program halted",0
Idle SYNC 4
POP 0,0
PREFIX :
% Devicespecific TRAP Handlers
% MMIXware Traps
:FTrap:Fopen IS :FTrap:Unhandled
:FTrap:Fclose IS :FTrap:Unhandled
:FTrap:Fread IS :FTrap:Unhandled
PREFIX :Fgets:
% Characters are read into MMIX's memory starting at address |buffer|,
% until either |size-1| characters have been read and stored or a
% newline character has been read and stored; the next byte in memory
% is then set to zero.
% If an error or end of file occurs before reading is complete, the
% memory contents are undefined and the value $-1$ is returned;
% otherwise the number of characters successfully read and stored is
% returned.
buffer IS $0
size IS $1
n IS $2
return IS $3
tmp IS $4
:FTrap:Fgets GET tmp,:rXX % instruction
AND tmp,tmp,#FF % Z value
BNZ tmp,Error % this is not StdIn
% Fgets from the keyboard
GET tmp,:rBB % get the $255 parameter: buffer, size
LDO buffer,tmp,0
LDO size,tmp,8
SET n,0
GET return,:rJ
JMP 1F
Loop PUSHJ tmp,:KeyboardC % read blocking from the keyboard
STBU tmp,buffer,n
ADDU n,n,1
CMP tmp,tmp,10 % newline
BZ tmp,Done
1H SUB size,size,1
BP size,Loop
Done SET tmp,0 % terminating zero byte
STBU tmp,buffer,n
PUT :rBB,n % result
PUT :rJ,return
POP 0,0
Error NEG tmp,1
PUT :rBB,tmp
POP 0,0
:FTrap:Fgetws IS :FTrap:Unhandled
PREFIX :Fwrite:
% The next |size| characters are written from MMIX's memory starting
% at address |buffer|. If no error occurs, 0~is returned;
% otherwise the negative value |n-size| is returned,
% where |n|~is the number of characters successfully written.
% we work with a pointer to the end of the buffer (last)
% and a negative offset towards this point (tolast)
% to have only a single ADD in the Loop.
last IS $0 buffer+size
tolast IS $1 n-size
n IS $1
return IS $2
tmp IS $3
:FTrap:Fwrite GET tmp,:rXX % instruction
AND tmp,tmp,#FF % Z value
BZ tmp,Error % this is stdin
CMP tmp,tmp,2 % StdOut or StdErr
BP tmp,Error % this is a File
% Fwrite to the screen
GET tmp,:rBB % get the $255 parameter: buffer, size
LDO last,tmp,0 % buffer
LDO tolast,tmp,8 % size
ADDU last,last,tolast
NEG tolast,tolast
GET return,:rJ
JMP 1F
Loop LDBU tmp+1,last,tolast
PUSHJ tmp,:ScreenC
ADD tolast,tolast,1
1H BN tolast,Loop
PUT :rBB,tolast
PUT :rJ,return
POP 0,0
Error NEG tmp,1
PUT :rBB,tmp
POP 0,0
PREFIX :Fputs:
% One-byte characters are written from MMIX's memory to the file,
% starting at address string, up to but not including the first
% byte equal to zero. The number of bytes written is returned,
% or $-1$ on error.
string IS $0
n IS $1
return IS $2
tmp IS $3
:FTrap:Fputs GET tmp,:rXX % instruction
AND tmp,tmp,#FF % Z value
BZ tmp,Error % this is stdin
CMP tmp,tmp,2 % StdOut or StdErr
BP tmp,Error % this is a File
% Fputs to the screen
GET return,:rJ
GET string,:rBB %get the $255 parameter
SET n,0
JMP 1F
Loop PUSHJ tmp,:ScreenC
ADD n,n,1
1H LDBU tmp+1,string,n
BNZ tmp+1,Loop
PUT :rJ,return
PUT :rBB,n
POP 0,0
Error NEG tmp,1
PUT :rBB,tmp
POP 0,0
:FTrap:Fputws IS :FTrap:Unhandled
:FTrap:Fseek IS :FTrap:Unhandled
:FTrap:Ftell IS :FTrap:Unhandled
% END of MMIXware
% Timer
PREFIX :TWait:
% $255 specifies the number of ms to wait
t IS #10 %offset of Timer t register
tbit IS $0
bits IS $1
tmp IS $2
ms IS $3
base IS $4
:FTrap:TWait SETH base,:IO:HI
SET tbit,1
SL tbit,tbit,:Interrupt:Timer
GET bits,:rQ
GET ms,:rBB %ms to wait
BNP ms,Done
ANDN tmp,bits,tbit
PUT :rQ,tmp %Clear Timer Interrupt
STTU ms,base,:IO:Timer+t
Loop SYNC 4
GET bits,:rQ
AND tmp,bits,tbit
BZ tmp,Loop %test Timer bit
Done STCO 0,base,:IO:Timer+t %switch Timer off
ANDN bits,bits,tbit
PUT :rQ,bits
PUT :rBB,0
POP 0,0
PREFIX :TDate:
% Get the current date in format YYYYMMDW
base IS $1
date IS $0
W IS $2
D IS $3
M IS $4
YY IS $5
tmp IS $6
:FTrap:TDate SETH base,:IO:HI
LDOU date,base,:IO:Timer %YYMDXXXW
AND W,date,#FF %W
SRU date,date,32
AND D,date,#FF %D
SRU date,date,8
AND M,date,#FF %M
SRU YY,date,8 %YY
SL D,D,8
OR date,W,D
SL M,M,16
OR date,date,M
SL YY,YY,32
OR date,date,YY
PUT :rBB,date %YYYYMMDW
POP 0,0
PREFIX :TTimeOfDay:
% Read the current Time in ms since midnight
ms IS #0C
base IS $0
current IS $1
:FTrap:TTimeOfDay SETH base,:IO:HI
LDTU current,base,:IO:Timer+ms
PUT :rBB,current
POP 0,0
PREFIX :TCount:
% Counter for Sokoban
tiOffset IS #10
base IS $0 % Adresse eines Counters
counter IS $1
tmp IS $2
offset IS $3
:FTrap:TCount SET offset,tiOffset
SETH base,:IO:HI
ADD offset,offset,:IO:Timer
SET tmp,1000 % t = 1000 ms
ORMH tmp,1000 % i = 1000 ms
STO tmp,base,offset % Daten beim Offset speichern
GET :Boot:count,:rBB % counter Adresse global speichern
POP 0,0
PREFIX :TInitTimer:
% Counter von Sokoban laden
:FTrap:TInitTimer GET :Boot:count,:rBB % counter Adresse global speichern
POP 0,0
% Video RAM
PREFIX :VPut:
% Put one pixel on the graphics display.
% In $255 we have in the Hi 32 bit the RGB value
% and in the low 32 bit the offset into the video ram
tmp IS $0
rgb IS $1
offset IS $2
:FTrap:VPut GET tmp,:rBB %get the $255 parameter: RGB, offset
SRU rgb,tmp,32
SLU offset,tmp,32
SRU offset,offset,32
SETH tmp,:VRAM:HI
STTU rgb,tmp,offset
PUT :rBB,0
POP 0,0
PREFIX :VGet:
% Return one pixel at the given offset from the graphics display.
% In $255 we have in the low 32 bit the offset into the video ram
tmp IS $0
rgb IS $1
offset IS $2
:FTrap:VGet GET tmp,:rBB %get the $255 parameter: RGB, offset
SLU offset,tmp,32
SRU offset,offset,32
SETH tmp,:VRAM:HI
LDTU rgb,tmp,offset
PUT :rBB,rgb
POP 0,0
% GPU
PREFIX :GPU:CMD:
CHAR IS #0100
RECT IS #0200
LINE IS #0300
BLT IS #0400
BLTIN IS #0500
BLTOUT IS #0600
PREFIX :GPU:
CMD IS 0
AUX IS 1
XY2 IS 4
X2 IS 4
Y2 IS 6
WHXY IS 8
WH IS 8
W IS 8
H IS #0A
XY IS #0C
X IS #0C
Y IS #0E
BBA IS #10
TBCOLOR IS #18 Text Background Color
TFCOLOR IS #1C Text Foreground Color
FCOLOR IS #20 Fill Color
LCOLOR IS #24 Line Color
CWH IS #28 Character Width and Height
CW IS #28
CH IS #2A
FW IS #30 Frame and Screen Width and Height
FH IS #32
SW IS #34
SH IS #36
PREFIX :GSize:
tmp IS $0
:FTrap:GSize SETH tmp,:IO:HI
LDTU tmp,tmp,:IO:GPU+:GPU:FW
PUT :rBB,tmp
POP 0,0
PREFIX :GSet
tmp IS $0
base IS $1
% Set the width and height for the next Rectangle
:FTrap:GSetWH GET tmp,:rBB %get the $255 parameter: w,h
SETH base,:IO:HI %base address of gpu -20
STTU tmp,base,:IO:GPU+:GPU:WH
POP 0,0
% Set the position for the next GChar,GPutStr,GLine Operation
:FTrap:GSetPos GET tmp,:rBB %get the $255 parameter: x,y
SETH base,:IO:HI %base address of gpu -20
STTU tmp,base,:IO:GPU+:GPU:XY
POP 0,0
:FTrap:GSetTextColor GET tmp,:rBB % background RGB, foreground RGB
SETH base,:IO:HI
STOU tmp,base,:IO:GPU+:GPU:TBCOLOR
POP 0,0
:FTrap:GSetFillColor GET tmp,:rBB % RGB
SETH base,:IO:HI
STTU tmp,base,:IO:GPU+:GPU:FCOLOR
POP 0,0