-
Notifications
You must be signed in to change notification settings - Fork 3
/
adventureland.asm.in
2941 lines (2806 loc) · 76.8 KB
/
adventureland.asm.in
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
;__________________________________________________________________________________________________
; Serial Input: 9600 baud, normal RS232 logic
; IN: P=7, X=2
; OUT: P=3, RF.1 = received character
; TRASHED: R8
B96IN_Return
SEP R3
B96IN
; Load the starting point for the LED animation
LDI HIGH KnightRider
PHI R8
LDI LOW KnightRider
PLO R8
B96StopBitLoop ; Wait for the stop bit
B3 B96StopBitLoop
LDI $FF ; Initialize input character in RF.1 to $FF
PHI RF
B96DrawLights
B3 B96FoundStartBit
LDA R8 ; load next bit pattern in LED animation
STR R2 ; put it on the stack
B3 B96FoundStartBit
OUT 4 ; output to LEDs
DEC R2 ; restore stack pointer to original value
B3 B96FoundStartBit
GLO R8 ; load the low byte of the current bit pattern pointer
SMI LOW KnightRider+44 ; is it at the end of the animation sequence?
B3 B96FoundStartBit
BNZ B96WaitStartBit ; if not, go burn CPU cycles and wait for the start bit
LDI LOW KnightRider ; now re-load the bit pattern pointer
B3 B96FoundStartBit
PLO R8
B96WaitStartBit
LDI $00 ; animation inner loop counter
B96StartBitLoop
NOP
B3 B96FoundStartBit
NOP
SMI $01
B3 B96FoundStartBit
NOP
NOP
B3 B96FoundStartBit
BNZ B96StartBitLoop
BR B96DrawLights
B96FoundStartBit
LDI $01 ; Set up D and DF, which takes about a quarter of a bit duration
SHR
BR B96SkipDelay
B96StartDelay
LDI $02
B96DelayLoop
SMI $01
BNZ B96DelayLoop
; When done with delay, D=0 and DF=1
B96SkipDelay ; read current bit
B3 B96IN4
SKP ; if BIT=0 (EF3 PIN HIGH), leave DF=1
B96IN4
SHR ; if BIT=1 (EF3 PIN LOW), set DF=0
GHI RF ; load incoming byte
SHRC ; shift new bit into MSB, and oldest bit into DF
PHI RF
LBDF B96StartDelay
STR R2 ; put new char on the stack
LDI LOW Rand_VarX ; load a pointer to the psuedo-random generator's X value
PLO R8
LDI HIGH Rand_VarX
PHI R8
LDN R8 ; get the X value
ADD ; and add the value of the input character, to make the generator's
STR R8 ; values non-deterministic
BR B96IN_Return
;__________________________________________________________________________________________________
; Serial Input: 9600 baud, inverted RS232 logic
; IN: P=7, X=2
; OUT: P=3, RF.1 = received character
; TRASHED: R8
Bi96IN_Return
SEP R3
Bi96IN
; Load the starting point for the LED animation
LDI HIGH KnightRider
PHI R8
LDI LOW KnightRider
PLO R8
Bi96StopBitLoop ; Wait for the stop bit
BN3 Bi96StopBitLoop
LDI $FF ; Initialize input character in RF.1 to $FF
PHI RF
Bi96DrawLights
BN3 Bi96FoundStartBit
LDA R8 ; load next bit pattern in LED animation
STR R2 ; put it on the stack
BN3 Bi96FoundStartBit
OUT 4 ; output to LEDs
DEC R2 ; restore stack pointer to original value
BN3 Bi96FoundStartBit
GLO R8 ; load the low byte of the current bit pattern pointer
SMI LOW KnightRider+44 ; is it at the end of the animation sequence?
BN3 Bi96FoundStartBit
BNZ Bi96WaitStartBit ; if not, go burn CPU cycles and wait for the start bit
LDI LOW KnightRider ; now re-load the bit pattern pointer
BN3 Bi96FoundStartBit
PLO R8
Bi96WaitStartBit
LDI $00 ; animation inner loop counter
Bi96StartBitLoop
NOP
BN3 Bi96FoundStartBit
NOP
SMI $01
BN3 Bi96FoundStartBit
NOP
NOP
BN3 Bi96FoundStartBit
BNZ Bi96StartBitLoop
BR Bi96DrawLights
Bi96FoundStartBit
LDI $01 ; Set up D and DF, which takes about a quarter of a bit duration
SHR
BR Bi96SkipDelay
Bi96StartDelay
LDI $02
Bi96DelayLoop
SMI $01
BNZ Bi96DelayLoop
; When done with delay, D=0 and DF=1
Bi96SkipDelay ; read current bit
BN3 Bi96IN4
SKP ; if BIT=0 (EF3 PIN HIGH), leave DF=1
Bi96IN4
SHR ; if BIT=1 (EF3 PIN LOW), set DF=0
GHI RF ; load incoming byte
SHRC ; shift new bit into MSB, and oldest bit into DF
PHI RF
LBDF Bi96StartDelay
STR R2 ; put new char on the stack
LDI LOW Rand_VarX ; load a pointer to the psuedo-random generator's X value
PLO R8
LDI HIGH Rand_VarX
PHI R8
LDN R8 ; get the X value
ADD ; and add the value of the input character, to make the generator's
STR R8 ; values non-deterministic
BR Bi96IN_Return
;__________________________________________________________________________________________________
; Serial Output: 9600 baud, normal RS232 logic
; IN: P=7, D = character to transmit, R2 is stack pointer
; OUT: P=3
; TRASHED: RF
B96OUT_Return
SEP R3
B96OUT
PHI RF ; save output character in RF.1
STR R2
SEX R2
OUT 4 ; set LEDs to output character
DEC R2
LDI 08H ; RF.0 is data bit counter
PLO RF
STBIT96 ; Send Start Bit (Space)
SEQ ; 2
NOP ; 5
NOP ; 8
GHI RF ; 10
SHRC ; 12 DF = 1st bit to transmit
PHI RF ; 14
PHI RF ; 16
NOP ; 19
BDF STBIT96_1 ; 21 First bit = 1?
BR QHI96 ; 23 bit = 0, output Space
STBIT96_1
BR QLO96 ; 23 bit = 1, output Mark
QHI96_1
DEC RF
GLO RF
BZ DONE96 ;AT 8.5 INSTRUCTIONS EITHER DONE OR REQ
;DELAY
NOP
NOP
QHI96
SEQ ; Q ON
GHI RF
SHRC ; PUT NEXT BIT IN DF
PHI RF
LBNF QHI96_1 ; 5.5 TURN Q OFF AFTER 6 MORE INSTRUCTION TIMES
QLO96_1
DEC RF
GLO RF
BZ DONE96 ; AT 8.5 INSTRUCTIONS EITHER DONE OR SEQ
;DELAY
NOP
NOP
QLO96
REQ ;Q OFF
GHI RF
SHRC ;PUT NEXT BIT IN DF
PHI RF
LBDF QLO96_1 ;5.5 TURN Q ON AFTER 6 MORE INSTRUCTION TIMES
DEC RF
GLO RF
BZ DONE96 ;AT 8.5 INSTRUCTIONS EITHER DONE OR REQ
;DELAY
NOP
LBR QHI96
DONE96 ;FINISH LAST BIT TIMING
NOP
NOP
DNE961
REQ ; Send stop bit: Q=0
BR B96OUT_Return
;__________________________________________________________________________________________________
; Serial I/O hooks
; Customized serial input routine
; IN: P=7
; OUT: P=3, RF.1 = received character
; TRASHED: R8
SerialInput
LBR 0000
; Customized serial output routine
; IN: P=7, D = character to transmit, R2 is stack pointer
; OUT: P=3
; TRASHED: RF
SerialOutput
LBR 0000
;__________________________________________________________________________________________________
; Serial Input: 4800 or lower baud, normal RS232 logic
; IN: P=7
; OUT: P=3, RF.1 = received character
; TRASHED: R8
B48IN_Return
SEP R3
B48IN
GHI RD ; GET RD.1
STR R2 ; PUSH RD.1 ON THE STACK
DEC R2
GLO RD ; GET RD.0
STR R2
DEC R2 ; PUSH RD.0 ON THE STACK
LDI 08H ; LOAD D WITH TOTAL BIT COUNT
PLO RD ; LOAD RD.0 WITH BIT COUNT
B48IBaud
LDI 00H
PHI RD ; LOAD RD.1 WITH Baud rate counter
; Load the starting point for the LED animation
LDI HIGH KnightRider
PHI R8
LDI LOW KnightRider
PLO R8
B48StopBitLoop ; Wait for the stop bit
B3 B48StopBitLoop
B48DrawLights
LDA R8 ; load next bit pattern in LED animation
STR R2 ; put it on the stack
OUT 4 ; output to LEDs
DEC R2 ; restore stack pointer to original value
B48CheckStart1
B3 B48FoundStartBit
GLO R8 ; load the low byte of the current bit pattern pointer
SMI LOW KnightRider+44 ; is it at the end of the animation sequence?
BNZ B48WaitStartBit ; if not, go burn CPU cycles and wait for the start bit
LDI LOW Rand_VarX ; we have to reset the pointer, so begin by instead
PLO R8
LDI HIGH Rand_VarX ; loading a pointer to the psuedo-random generator's X value
PHI R8
LDN R8
ADI $01 ; and incrementing this value in memory, to make the generator's
STR R8 ; values non-deterministic
B48CheckStart2
B3 B48FoundStartBit
LDI LOW KnightRider ; now re-load the bit pattern pointer
PLO R8
LDI HIGH KnightRider
PHI R8
B48WaitStartBit
LDI $00 ; animation inner loop counter
B48StartBitLoop
SMI $01
NOP
NOP
B48CheckStart3
B3 B48FoundStartBit
NOP
NOP
BNZ B48StartBitLoop
BR B48DrawLights
B48FoundStartBit
GHI RD
SHR
SHR
SMI 01H
B48ILoop2 ; WAIT .25 BIT TIME
SMI 01H
BNZ B48ILoop2
GHI RD
B48ILoop3
SMI 01H
BNZ B48ILoop3 ; WAIT 1 BIT TIME
B48ILoop4
GHI RF ; GET INCOMING FORMING CHARACRTER SO FAR
B3 B48ILoop4Next1 ; CHECK INCOMING BIT VALUE
ORI 80H ; IF INCOMING BIT WAS A MARK THEN SET BIT 8 OF INCOMING CHARACTER VALUE
BR B48ILoop4Next2
B48ILoop4Next1
ANI 7FH ; CLEAR INCOMING BIT
SEX R2 ; WASTE ONE MACHINE CYCLE
B48ILoop4Next2
PHI RF ; SAVE INCOMING FORMING CHARACTER
DEC RD ; DECREMENT THE BIT COUNT VALUE
GLO RD ; GET CURRENT BIT COUNT VALUE
BZ B48ILoop4Done ; DONE IF BIT COUNT IS ZERO
GHI RF ; GET INCOMING FORMING CHARACTER
SHR ; SHIFT INCOMING FORMING CHARACTER ONE BIT RIGHT
PHI RF ; SAVE IT, INCOMING FORMING CHARACTER IS READY FOR THE NEXT BIT
; WAIT UNTIL THIS BIT TIME IS DONE
GHI RD
NOP ; WASTE THREE MACHINE CYCLES
SMI 07H ; CORRECTION FOR BYTES USED
B48ILoop4_1
SMI 01H
BNZ B48ILoop4_1
BR B48ILoop4
B48ILoop4Done
INC R2 ; INCREMENT STACK POINTER
LDN R2 ; LOAD D FROM STACK
PLO RD ; STORE IN RD.0
INC R2 ; INCREMENT STACK POINTER
LDN R2 ; LOAD D FROM STACK
PHI RD ; STORE IN RD.1 , STACK AND RD RESTORED
BR B48IN_Return ; RETURN
;__________________________________________________________________________________________________
; Serial Output: 4800 or lower baud, normal RS232 logic
; IN: P=7, D = character to transmit, R2 is stack pointer
; OUT: P=3
; TRASHED: RF
B48OUT_Return
SEP R3
B48OUT
PHI RF ; save output character in RF.1
STR R2
SEX R2
OUT 4 ; set LEDs to output character
DEC R2
GHI RD ; GET RD.1
STXD ; PUSH RD.1 ON THE STACK
B48OBaud
LDI 00H
PHI RD ; STORE BAUD COUNTER IN RD.1
LDI 80H ; LOAD D WITH 80H
PLO RF ; SAVE BIT COUNTER IN RF.0
GHI RD ; WAIT 1 BIT TIME MINUS 8 MACHINE CYCLES
SMI $02
B48OStartBit
SEQ ; SET Q, OUTPUT START BIT , RS-232 MARK
B48OLoop1
SMI 01H
BNZ B48OLoop1
GHI RF ; GET CHARACTER TO OUTPUT
SHR ; SHIFT CHARACTER ONE BIT RIGHT , DF EQUAL BIT TO OUTPUT
BDF B48ODataSpace ; SKIP IF BIT TO SEND IS A RS-232 SPACE
B48ODataMark
SEQ ; SET Q, BIT TO SEND IS A RS-232 MARK
BR B48OLoop1Next1 ; SKIP
B48ODataSpace
REQ ; RESET Q, BIT TO SEND IS A RS-232 SPACE
SEX R2 ; WASTE TWO MACHINE CYCLES
B48OLoop1Next1
PHI RF ; SAVE CHARACTER
GLO RF ; LOAD D WITH RF.0, GET BIT COUNTER
SHR ; SHIFT BIT COUNTER VALUE ONE BIT RIGHT
PLO RF ; SAVE NEW BIT COUNTER VALUE
BZ B48OLoop1Done ; DONE
GHI RD ; WAIT 1 BIT TIME
SMI 07H ; CORRECTION FOR BYTES USED
SEX R2 ; WASTE TWO MACHINE CYCLES
NOP ; WASTE THREE MACHINE CYCLES
BR B48OLoop1 ; CONTINUE UNTIL DONE
B48OLoop1Done
GHI RD ; FINISH THE DELAY OF X MACHINE CYCLES
SMI 04H
B48OLoop2
SMI 01H
BNZ B48OLoop2
B48OStopBit
REQ ; RESET Q , RESET THE RS-232 OUTPUT TO A RS-232 MARK
; START SENDING A STOP BIT
GHI RD ; WAIT 1 BIT TIME
B48OLoop3
SMI 01H
BPZ B48OLoop3
INC R2 ; INCREMENT STACK POINTER
LDN R2 ; LOAD D FROM STACK
PHI RD ; STORE IN RD.1, STACK AND RD RESTORED
BR B48OUT_Return
;__________________________________________________________________________________________________
; String print routine
; IN: R8 = pointer to null-terminated string
; OUT: N/A
; TRASHED: R7, R8, RF
OutString
LDI HIGH SerialOutput
PHI R7
LDI LOW SerialOutput
PLO R7
OutStrLoop1
LDA R8
BZ OutStrDone
SEP R7
BR OutStrLoop1
OutStrDone
SEP R5
;__________________________________________________________________________________________________
; Print a 2-digit number
; IN: D = number to print, R8 = pointer to start of string
; OUT: N/A
; TRASHED: D, R7
Print2Digit
PHI R7 ; save number to print
LDI $00
PLO R7
GHI R7
P2D_Tens
SMI 10
BL P2D_TensDone
INC R7
BR P2D_Tens
P2D_TensDone
ADI 10 ; D is now number of singles
PHI R7
GLO R7
LSNZ ; if there are no tens,
LDI ' '-'0' ; use space as filler char.
ADI '0'
STR R8 ; store the tens digit
INC R8
LDI $30 ; ASCII 0
PLO R7
GHI R7
P2D_Ones
SMI 1
BL P2D_OnesDone
INC R7
BR P2D_Ones
P2D_OnesDone
GLO R7
STR R8
DEC R8
SEP R5
;__________________________________________________________________________________________________
; Clear screen
; IN: N/A
; OUT: N/A
; TRASHED: R7, R8, RF
ClearScreen
LDI HIGH ClsMsg
PHI R8
LDI LOW ClsMsg
PLO R8
SEP R4
DW OutString
SEP R5
;__________________________________________________________________________________________________
; Generate a psuedo-random byte
; IN: N/A
; OUT: D=psuedo-random number
; TRASHED: R7
GenRandom
LDI LOW Rand_VarX
PLO R7
LDI HIGH Rand_VarX
PHI R7
SEX R7
LDN R7 ; D = VarX
ADI $01
STR R7
INC R7
LDA R7 ; D = VarA
INC R7
XOR ; D = VarA XOR VarC
DEC R7
DEC R7
DEC R7
XOR ; D = VarA XOR VarC XOR VarX
INC R7
STR R7 ; VarA = D
INC R7
ADD
STXD
SHR
XOR
INC R7
INC R7
ADD
STR R7
SEP R5
;__________________________________________________________________________________________________
; Restore internal variables to starting state
; IN: N/A
; OUT: N/A
; TRASHED: R7, R8, R9
GameReset
LDI LOW Array_I2 ; start by initializing item locations
PLO R8
LDI HIGH Array_I2
PHI R8
LDI LOW Array_IA
PLO R9
LDI HIGH Array_IA
PHI R9
LDI IL
PLO R7
GRLoop1
LDA R8
STR R9
INC R9
DEC R7
GLO R7
BNZ GRLoop1
INC R9
INC R9
LDI $00
STR R9 ; Loadflag = 0
INC R9
STR R9 ; Endflag = 0
INC R9
STR R9 ; Darkflag = 0
LDI AR
INC R9
STR R9 ; Room = AR
LDI LI
INC R9
STR R9 ; lamp_oil = LT
LDI $00
INC R9
STR R9
INC R9
STR R9 ; state_flags = 0
SEP R5
;__________________________________________________________________________________________________
; Main program starting point
GameStart
; The first thing we need to do is to configure our Serial I/O routines to work with the current settings
LDI HIGH BAUD
PHI R7
LDI LOW BAUD
PLO R7
LDA R7
PHI RE
LDN R7
PLO RE
SMI $02
BNZ Is4800orLess
; set up our serial i/o pointers to use 9600 baud normal logic
LDI HIGH SerialInput+1
PHI R8
LDI LOW SerialInput+1
PLO R8
LDI HIGH B96IN
STR R8
INC R8
LDI LOW B96IN
STR R8
INC R8
INC R8
LDI HIGH B96OUT
STR R8
INC R8
LDI LOW B96OUT
STR R8
; if RS232 logic level is inverted, set up serial input pointer to use 9600 baud inveted logic
GHI RE
ANI $01
BNZ BaudHandled
DEC R8
DEC R8
DEC R8
LDI LOW Bi96IN
STR R8
DEC R8
LDI HIGH Bi96IN
STR R8
BR BaudHandled
Is4800orLess
; set up our serial i/o pointers to use 4800 baud normal logic
LDI HIGH SerialInput+1
PHI R8
LDI LOW SerialInput+1
PLO R8
LDI HIGH B48IN
STR R8
INC R8
LDI LOW B48IN
STR R8
INC R8
INC R8
LDI HIGH B48OUT
STR R8
INC R8
LDI LOW B48OUT
STR R8
; use SMC (self-modifying code) to set the timers in 4800 baud output routine
LDI HIGH B48OBaud+1
PHI R8
LDI LOW B48OBaud+1
PLO R8
GLO RE
STR R8
; use SMC to set the timers in 4800 baud input routine
LDI HIGH B48IBaud+1
PHI R8
LDI LOW B48IBaud+1
PLO R8
GLO RE
STR R8
BaudHandled
GHI RE
ANI $01
LBNZ LogicHandled
; use SMC to modify the 9600 baud output routine to use inverted logic
LDI HIGH STBIT96
PHI R8
LDI LOW STBIT96
PLO R8
LDI $7A ; REQ
STR R8
LDI HIGH QHI96
PHI R8
LDI LOW QHI96
PLO R8
LDI $7A ; REQ
STR R8
LDI HIGH QLO96
PHI R8
LDI LOW QLO96
PLO R8
LDI $7B ; SEQ
STR R8
LDI HIGH DNE961
PHI R8
LDI LOW DNE961
PLO R8
LDI $7B ; SEQ
STR R8
; use SMC to modify the 4800 baud output routine to use inverted logic
LDI HIGH B48OStartBit
PHI R8
LDI LOW B48OStartBit
PLO R8
LDI $7A ; REQ
STR R8
LDI HIGH B48ODataMark
PHI R8
LDI LOW B48ODataMark
PLO R8
LDI $7A ; REQ
STR R8
LDI HIGH B48ODataSpace
PHI R8
LDI LOW B48ODataSpace
PLO R8
LDI $7B ; SEQ
STR R8
LDI HIGH B48OStopBit
PHI R8
LDI LOW B48OStopBit
PLO R8
LDI $7B ; SEQ
STR R8
; use SMC to modify the 4800 baud input routine to use inverted logic
LDI HIGH B48StopBitLoop
PHI R8
LDI LOW B48StopBitLoop
PLO R8
LDI $3E ; BN3
STR R8
LDI HIGH B48CheckStart1
PHI R8
LDI LOW B48CheckStart1
PLO R8
LDI $3E ; BN3
STR R8
LDI HIGH B48CheckStart2
PHI R8
LDI LOW B48CheckStart2
PLO R8
LDI $3E ; BN3
STR R8
LDI HIGH B48CheckStart3
PHI R8
LDI LOW B48CheckStart3
PLO R8
LDI $3E ; BN3
STR R8
LDI HIGH B48ILoop4+1
PHI R8
LDI LOW B48ILoop4+1
PLO R8
LDI $3E ; BN3
STR R8
LogicHandled
BR Do_Main
Exit
LDI $8B
PHI R0
LDI $5E
PLO R0
SEX R0
SEP R0 ; jump back to the monitor program
Do_Main
; beginning of main() function
; Print welcome message
LDI HIGH StartingMsg
PHI R8
LDI LOW StartingMsg
PLO R8
SEP R4
DW OutString
; start of main loop
MainLoad
; reset all game state
SEP R4
DW GameReset
; load game if possible
SEP R4
DW Do_LoadGame
; clear screen
SEP R4
DW ClearScreen
; look()
SEP R4
DW Do_Look
; NV[0] = 0
LDI LOW Array_NV
PLO R9
LDI HIGH Array_NV
PHI R9
LDI $00
STR R9
; turn()
SEP R4
DW Do_Turn
MainGetInput
; get_input()
SEP R4
DW Do_GetInput
; if command parsing failed, try again
BNZ MainGetInput
; turn()
SEP R4
DW Do_Turn
; reload R9 to point to Endflag
LDI LOW Endflag
PLO R9
LDI HIGH Endflag
PHI R9
LDN R9
BNZ Exit ; quit if endflag != 0
DEC R9
LDN R9
BNZ MainLoad ; loop back and re-load if loadflag != 0
; deal with lamp oil
LDI LOW (Array_IA+9)
PLO RA
LDI HIGH (Array_IA+9)
PHI RA
LDN RA
SMI $FF
BNZ MainNoLamp
LDI LOW LampOil
PLO R9
LDI HIGH LampOil
PHI R9
LDN R9
SMI $01
STR R9 ; lamp_oil--
BPZ LampNotEmpty
LDI HIGH LampEmptyMsg ; print Lamp is Empty message
PHI R8
LDI LOW LampEmptyMsg
PLO R8
SEP R4
DW OutString
LDI $00
STR RA ; IA[9] = 0
BR MainNoLamp
LampNotEmpty
SMI 25 ; is our oil level < 25?
BPZ MainNoLamp
LDI HIGH LampLow1Msg ; print Lamp is low message
PHI R8
LDI LOW LampLow1Msg
PLO R8
SEP R4
DW OutString
LDI HIGH PrintNumber
PHI R8
LDI LOW PrintNumber
PLO R8
LDN R9 ; D = lamp_oil
SEP R4
DW Print2Digit
SEP R4
DW OutString
LDI HIGH LampLow2Msg
PHI R8
LDI LOW LampLow2Msg
PLO R8
SEP R4
DW OutString
MainNoLamp
; NV[0] = 0
LDI LOW Array_NV
PLO R9
LDI HIGH Array_NV
PHI R9
LDI $00
STR R9
; turn()
SEP R4
DW Do_Turn
MainLoopTail
; reload R9 to point to Endflag
LDI LOW Endflag
PLO R9
LDI HIGH Endflag
PHI R9
LDN R9
BNZ Exit ; if endflag != 0, quit
DEC R9
LDN R9
BNZ MainLoad ; if loadflag != 0, loop back and re-load
BR MainGetInput ; otherwise, get next command
;__________________________________________________________________________________________________
; Adventure get_action_variable() function
; IN: P=F, RE=pAcVar
; OUT: P=3, D=value
; TRASHED: N/A
GAV_Return
SEP R3
Sub_GetActionVariable
INC RE
INC RE
GAV_Loop1
INC RE
LDN RE
BZ GAV_FoundVar
INC RE
BR GAV_Loop1
GAV_FoundVar
DEC RE
LDN RE
BR GAV_Return
;__________________________________________________________________________________________________
; Adventure get_input() function
; IN: N/A
; OUT: D = return value (1 if failed, 0 if command OK)
; TRASHED: R7, R8, R9, RA, RB, RC, RD, RF
Do_GetInput
; print input prompt
LDI HIGH InputPromptMsg
PHI R8
LDI LOW InputPromptMsg
PLO R8
SEP R4
DW OutString
; now we are in the gets() function. set up loop variables
LDI $00
PLO RA ; RA.0 is character counter; only 79 are allowed
LDI HIGH Array_TPS
PHI R9
LDI LOW Array_TPS
PLO R9 ; R9 is pointer to input line
GILoop1
; wait for key press
LDI HIGH SerialInput
PHI R7
LDI LOW SerialInput
PLO R7
SEP R7
; load R7 to point to serial output routine in case I need to print. this saves code space
LDI HIGH SerialOutput
PHI R7
LDI LOW SerialOutput
PLO R7
; handle backspace
GHI RF
SMI $8
BZ GIBackspace
GHI RF
SMI $7F
BNZ GILoop1N1
GIBackspace
GLO RA ; if line length is 0
BZ GILoop1 ; then just go back for another input character
LDI $08 ; otherwise, erase last character
SEP R7
LDI $20 ; ' '
SEP R7
LDI $08 ; '\b'
SEP R7
DEC RA ; decrement character count