-
Notifications
You must be signed in to change notification settings - Fork 1
/
io.asm
2022 lines (1926 loc) · 69 KB
/
io.asm
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
;****************************************************************************
;
; MC70 - Firmware for the Motorola MC micro trunking radio
; to use it as an Amateur-Radio transceiver
;
; Copyright (C) 2004 - 2012 Felix Erckenbrecht, DG1YFE
;
; This file is part of MC70.
;
; MC70 is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; MC70 is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with MC70. If not, see <http://www.gnu.org/licenses/>.
;
;
;
;****************************************************************************
;*************
; I O
;*************
;
;
;****************
; I O I N I T
;****************
;
; Initialisiert I/O :
; - Port2 DDR ( SCI TX, PLL T/R Shift )
; - Port6 DDR ( PTT Syn Latch )
; - Port5 DDR ( EXT Alarm )
; - Port5 Data ( EXT Alarm off (1) )
; - RP5CR (HALT disabled)
; - I2C (Clock output, Clock=0)
; - Shift Reg (S/R Latch output, S/R Latch = 0, S/R init)
; - SCI TX = 1 (Pullup)
;
; Parameter: keine
;
; Ergebnis : nix
;
; changed Regs: A,B
;
;
io_init
aim #%11100111,RP5CR ; do not wait for "Memory Ready", internal SRAM is fast enough
; also deactivate "HALT" input, Port53 is used as GPIO
oim #%0100, RMCR ; set asynchronous mode for SCI, to use P22 as GPIO
; (P22 is SCI clock I/O in synchronous mode)
ldab #%10110100
stab Port2_DDR_buf ; Clock (I2C),
stab Port2_DDR ; SCI TX, T/R Shift (PLL), Shift Reg Latch auf Ausgang
; I2C Init
aim #%11111011,Port2_Data ; I2C Clock = 0
;ShiftReg Init
aim #%01111111,Port2_Data ; Shift Reg Latch = 0
;SCI TX
oim #%10000, Port2_Data ; SCI TX=1
clr SR_data_buf ; clear shift reg buffer
ldaa #~(SR_RFPA) ; disable PA
ldab #(SR_nTXPWR + SR_nCLKSHIFT + SR_9V6)
; disable Power control, disable clock shift, enable 9,6 V
jsr send2shift_reg ; Shift register requires initialization within
; 0.5s after the radio is connected to power.
; An R-C combination (tau = 0.47 s) tristates
; the SR output for a maximum of 0.5 s after
; 5 V are present. (Up to 1.5 Volts are recognized as low)
; If SR is not initialized, the random state
; might shut-off the radio by pulling STBY&9,6V low
; This state would persist as long as 5 V are on.
; Since 5 V are directly generated from (unswitched) B+
; this state would persist until power connection is
; disabled.
; Port 5
ldab #%00001000
stab Port5_DDR ; EXT Alarm auf Ausgang, Alles andere auf Input
stab Port5_DDR_buf
oim #BIT_SQEXT, PORT_SQEXT ; EXT Alarm off (Hi)
; Port 6
ldab #%00001100
stab Port6_DDR_buf
stab Port6_DDR ; A16 (Bank Switch), PTT Syn Latch auf Ausgang
aim #%10011011, Port6_Data ; Bank 0 wählen
clr led_buf
clr arrow_buf
clr arrow_buf+1
clr sql_ctr
clr ui_ptt_req ;
clr tone_timer
rts
#ifdef EVA9
;*****************************
; I O I N I T S E C O N D
;*****************************
;
; Secondary I/O Initialization (if device is switched on):
;
; - enable external EEPROM
;
; Parameter: none
;
; Returns : nothing
;
; changed Regs: A,B
io_init_second
aim #%00000000, Port5_Data ; EEPROM on (/EEP Pwr Stb = 0)
oim #%10000000, RP5CR ; Set Standby Power Bit
rts
#endif
;****************************
; S E N D 2 S h i f t _ R e g
;****************************
;
; AND is performed before OR !
;
; Parameter : A - AND-Value
; B - OR-Value
;
; changed Regs: A,B,X
;
send2shift_reg
inc bus_busy ; disable IRQ Watchdog Reset
inc tasksw_en
anda SR_data_buf
staa SR_data_buf
orab SR_data_buf
stab SR_data_buf
ldaa #8 ; 8 Bit senden
s2sr_loop
psha ; save bit counter
lslb ; shift MSB to carryflag
bcs s2sr_bitset ; branch if Bit set
I2C_DL ; Bit clear, set data line to zero
I2C_CH
I2C_CL ; Clock Hi/Lo toggle
bra s2sr_dec
s2sr_bitset
I2C_DH ; Data Hi
I2C_CH
I2C_CL ; Clock Hi/Lo toggle
s2sr_dec
pula ; restore bit counter
deca ; bit counter--
bne s2sr_loop
I2C_DI ; set Data line Input & Hi (via ext. Pull-Up)
oim #BIT_SRLATCH, PORT_SRLATCH
aim #~BIT_SRLATCH,PORT_SRLATCH ; toggle Shift Reg Latch - present data on shift reg outputs
dec bus_busy ; disable IRQ Watchdog Reset
dec tasksw_en
rts
;****************
; S E N D 2 P L L
;****************
;
; Parameter : A - Reg Select (0=AN, 1=R)
; B = Divider Value ( A )
; X = Divider Value ( N / R)
;
; gültige Werte für N: 3-1023
; A: 0-127
; R: 3-16383
;
; changed Regs: A,B,X
;
send2pll
inc bus_busy ; disable IRQ Watchdog Reset
inc tasksw_en
tsta
bne set_r ; which register to set
set_an
lslb ; shift MSB to Bit 7 (A=7 Bit)
ldaa #6 ; 6 Bit shiften
set_an_loop
lslb ; B ein Bit nach links
xgdx
rolb ; X/lo ein Bit nach links, Bit von B einfügen
rola ; X/hi ein Bit nach links, Bit von X/lo einfügen
xgdx
deca ; Counter --
bne set_an_loop
ldaa #18 ; A/N counter 17 Bit (10+7) + Control Bit(=0)
bra pll_loop ; send Bit to PLL Shift Reg
set_r
xgdx
lsld
lsld
orab #2 ; Set Control Bit (select R)
xgdx
ldaa #15 ; 14 Bit / R counter + Control Bit
pll_loop
lslb ; B ein Bit nach links
xgdx
rolb ; X/lo ein Bit nach links, Bit von B einfügen
rola ; X/hi ein Bit nach links, Bit von X/lo einfügen
; Shift next Bit into Carry Flag
xgdx
psha ; A sichern
bcc pll_bit_is_0 ; test Bit
I2C_DH ; I2C Data = high
bra pll_nextbit
pll_bit_is_0
I2C_DL ; I2C Data = low
pll_nextbit
I2C_CTGL ; I2C Clock, high/low toggle
pula ; restore A
deca ; Counter--
bne pll_loop
I2C_DI ; I2C Data wieder auf Input
oim #BIT_PLLLATCH, PORT_PLLLATCH; PLL Syn Latch auf Hi
nop
nop
aim #~BIT_PLLLATCH, PORT_PLLLATCH ; PLL Syn Latch auf Lo
dec bus_busy ; re-enable Watchdog Reset
dec tasksw_en
rts
;
;
;
;**********************************************
; I 2 C
;**********************************************
;
;*******************
; I 2 C S T A R T
;*******************
;
; I2C "START" Condition senden
;
; changed Regs: NONE
;
i2c_start
psha
I2C_DH ; Data Leitung auf Hi / CPU auf Eingang
I2C_CH ; Clock Hi
I2C_DL ; Datenleitung auf low
I2C_CL ; Clock Lo
pula
rts
;******************
; I 2 C S T O P
;******************
;
; I2C "STOP" Condition senden
;
; changed Regs: NONE
;
i2c_stop
psha
I2C_DL ; Datenleitung auf low
I2C_CH ; Clock Leitung auf Hi
I2C_DH ; Data Leitung auf Hi / CPU auf Eingang
I2C_CL ; Clock Leitung auf Lo
pula
rts
;***************
; I 2 C A C K
;***************
;
; I2C "ACK" senden
; Bestätigung des Adress und Datenworts -> 0 im 9. Clock Zyklus senden
;
; changed Regs: NONE
;
i2c_ack
psha
I2C_DL ; Data low
I2C_CH ; Clock Hi
I2C_CL ; Clock Lo
I2C_DI ; Data wieder auf Eingang
pula
rts
;***********************
; I 2 C T S T A C K
;***********************
;
; I2C "ACK" prüfen
; Bestätigung des Adress und Datenworts -> 0 im 9. Clock Zyklus senden
;
; Ergebnis : A - 0 : Ack
; 1 : No Ack / Error
;
; changed Regs: A
;
i2c_tstack
I2C_DI ; Data Input
I2C_CH ; I2C Clock Hi
ldaa Port2_Data ;
I2C_CLb ; I2C Clock Lo
anda #$02 ; I2C Datenbit isolieren
lsra ; an Pos. 0 schieben
rts
;*************
; I 2 C T X
;*************
;
; 8 Bit auf I2C Bus senden
;
; Parameter: B - Datenwort, wird mit MSB first auf I2C Bus gelegt
;
;
;
i2c_tx
pshb
psha
ldaa #8 ; 8 Bit senden
itx_loop
psha ; Bitcounter sichern
lslb ; MSB in Carryflag schieben
bcs itx_bitset ; Sprung, wenn Bit gesetzt
I2C_DL ; Bit gelöscht, also Datenleitung 0
I2C_CH
I2C_CL ; Clock Hi/Lo toggle
bra itx_dec
itx_bitset
I2C_DH ; Data Hi
I2C_CH
I2C_CL ; Clock Hi/Lo toggle
itx_dec
pula
deca ; A--
bne itx_loop
I2C_DI ; Data auf Input & Hi
pula
pulb
rts
;*************
; I 2 C R X
;*************
;
; Byte auf I2C Bus empfangen
;
; Ergebnis : B - Empfangenes Byte
;
; changed Regs: B
;
i2c_rx
psha
pshx
clra
psha ; temporären Speicher für empfangenes Byte
tsx
I2C_DI ; I2C Data Input
ldaa #$80 ; Mit MSB beginnen
irx_loop
I2C_CHb
ldab Port2_Data ; Daten einlesen
andb #%10
tstb ; Bit gesetzt?
beq irx_shift ; Nein, dann kein Bit einfügen
tab
oraa 0,x ; Wenn gesetzt, dann Bit einfügen
staa 0,x ; und speichern
tba
irx_shift
I2C_CLb ; Clock toggle
lsra ; nächstes Bit
bcc irx_loop ; wenn noch ein Bit zu empfangen ist -> loop
pulb ; Ergebnis holen
pulx ; X und
pula ; A wiederherstellen
rts
;**********************************************
; S C I
;**********************************************
;***********************
; I N I T _ S C I
;***********************
sci_init
ldab #(SYSCLK/(32* 1200 ))-1 ;
stab TCONR ; Counter für 1200 bps
ldab #%10000
stab TCSR3 ; Timer 2 aktivieren, Clock = E (Sysclk/4=2MHz), no Timer output
ldab #%110100 ; 7 Bit, Async, Clock=T2
stab RMCR
ldab #%110 ; 1Stop Bit, Odd Parity, Parity enabled
stab TRCSR2
ldab #%1010
stab TRCSR1 ; TX & RX enabled, no Int
rts
;************************
; S C I R X
;************************
; Parameter: A - Status (0=RX ok, 3=no RX)
; B - rxd Byte
;
; changed Regs : A, B, X
;
; required Stack Space : 2
;
sci_rx
ldab io_inbuf_r ; Zeiger auf Leseposition holen
cmpb io_inbuf_w ; mit Schreibposition vergleichen
beq src_no_data ; Wenn gleich sind keine Daten gekommen
ldx #io_inbuf ; Basisadresse holen
abx ; Zeiger addieren, Leseadresse berechnen
ldaa 0,x ; Datenbyte aus Puffer lesen
incb ; Zeiger++
andb #$io_inbuf_mask ; Im gültigen Bereich bleiben
stab io_inbuf_r ; neue Zeigerposition speichern
tab ; Datenbyte nach B
clra ; A = 0
rts
src_no_data
ldaa #3
clrb
rts
;************************
; S C I R E A D
;************************
;
; Zeichen vom serieller Schnittstelle lesen (blocking)
;
; Parameter : B - rxd Byte
;
; changed Regs : A, B, X
;
; required Stack Space : 2
;
sci_read
ldab io_inbuf_r ; Zeiger auf Leseposition holen
cmpb io_inbuf_w ; mit Schreibposition vergleichen
beq sci_read ; Wenn gleich sind keine Daten gekommen -> warten
ldx #io_inbuf ; Basisadresse holen
abx ; Zeiger addieren, Leseadresse berechnen
ldaa 0,x ; Datenbyte aus Puffer lesen
incb ; Zeiger++
andb #$io_inbuf_mask ; Im gültigen Bereich bleiben
stab io_inbuf_r ; neue Zeigerposition speichern
tab ; Datenbyte nach B
clra ; A = 0
rts
;************************
; S C I R X M
;************************
;
; Echo/Kommandobestätigung lesen
;
; Parameter: none
;
; Returns: A - raw value ( Bit 0-6)
; Status (Bit 7) (0=RX ok, 1=no RX)
; B - converted Byte (Key convert Table)
;
; changed Regs : A, B
;
; required Stack Space : 2
;
sci_rx_m
ldab io_menubuf_r ; Zeiger auf Leseposition holen
cmpb io_menubuf_w ; mit Schreibposition vergleichen
bne srdm_cont
ldaa #-1
clrb
rts
;************************
; S C I R E A D M
;************************
;
; Eingabe von Display lesen (blocking)
;
; Parameter: none
;
; Ergebnis : A : raw data
; B : converted data
;
; changed Regs : A, B
;
; required Stack Space : 4
;
sci_read_m
ldab io_menubuf_r ; Zeiger auf Leseposition holen
cmpb io_menubuf_w ; mit Schreibposition vergleichen
bne srdm_cont ; Wenn nicht gleich sind Daten gekommen -> weitermachen
swi ; sonst Taskswitch
ldd m_timer ; check m_timer
bne sci_read_m ; loop if not zero
ldaa #-1
rts ; otherwise return with error code
srdm_cont
ldx #io_menubuf ; Basisadresse holen
abx ; Zeiger addieren, Leseadresse berechnen
ldaa 0,x ; Datenbyte aus Puffer lesen
incb ; Zeiger++
andb #io_menubuf_mask ; Im Bereich 0-7 bleiben
stab io_menubuf_r ; neue Zeigerposition speichern
tab ; Datenbyte nach B
pshx
ldx #key_convert ; index key convert table
abx
ldab 0,x ; Key übersetzen
pulx
rts
;************************
; S C I T X
;************************
;
; Transfer char to/via SCI
;
; Parameter: none
;
; Returns : A - Status (0=ok, 1=buffer full)
; B - TX Byte
;
; changed Regs : none
;
; required Stack Space : 3
;
sci_tx
psha
stx_wait_tdr_empty1
ldaa TRCSR1
anda #%00100000
beq stx_wait_tdr_empty1 ; sicher gehen dass TX Register leer ist
stx_writereg
stab TDR ; Byte in Senderegister
stx_wait_tdr_empty2
; ldaa TRCSR1
; anda #%00100000
; beq stx_wait_tdr_empty2 ; Warten bis es gesendet wurde
pula
rts
;
;************************
; S C I T X W
;************************
;
; Sendet Zeichen in B nach Ablauf des LCD_TIMER. Setzt abhängig von gesendeten
; Zeichen den Timer neu. Berücksichtigt unterschiedliche Timeouts für $78, $4F/$5F und Rest
;
; Parameter : B - zu sendendes Zeichen
;
; Ergebnis : Nichts
;
; changed Regs : None
;
; required Stack Space : 6
;
sci_tx_w
pshb
psha
pshx ; x sichern
stw_chk_lcd_timer
ldaa lcd_timer ; lcd_timer holen
beq stw_wait_tdr_empty1 ; warten falls dieser >0 (LCD ist noch nicht bereit)
swi ; Taskswitch
bra stw_chk_lcd_timer
stw_wait_tdr_empty1
ldaa TRCSR1
anda #%00100000
beq stw_wait_tdr_empty1
stw_writereg
stab TDR
stw_wait_tdr_empty2
ldaa TRCSR1
anda #%00100000
swi
beq stw_wait_tdr_empty2
tba
oraa #$10
cmpa #$5D ; auf 4D/5D prüfen - extended char
beq stw_end ; nächstes Zeichen OHNE Delay senden
oraa #$01
cmpa #$5F ; auf 4E/4F/5E/5F prüfen - extended char
beq stw_end ; nächstes Zeichen OHNE Delay senden
cmpb #$78 ; LCD Clear Zeichen?
bcs stw_10ms ; Alles was <$78 ist mit normalem Delay
ldab #LCDDELAY*4 ; vierfacher Timeout für Clear & Reset Befehle
stab lcd_timer
bra stw_end
stw_10ms
ldab #LCDDELAY ; normaler Timeout für Rest (auÃer 4f/5f)
stab lcd_timer
stw_end
pulx
pula
pulb
rts
;************************
; C H E C K I N B U F
;************************
;
; Parameter : none
; Result : A - Bytes in Buffer
;
check_inbuf
ldaa io_inbuf_w
suba io_inbuf_r
anda #io_inbuf_mask
rts
;
;****************
; S C I A C K
;****************
;
; Parameter : B - gesendetes Zeichen, das bestätigt werden soll
;
; Result : A - 0 = OK
; 1 = Error / Timeout
;
; changed Regs: X
;
; required Stack Space : 13 / 4 + putchar 'p'
;
;
sci_ack
pshb ; Zeichen sichern
ldaa #1
psha
sak_empty_buf
jsr check_inbuf ; Empfangspuffer überprüfen
tsta
beq sak_start_chk ; Wenn kein Zeichen
decb
beq sak_start_chk ; oder ein Zeichen drin ist, mit Auswertung fortsetzen
jsr sci_read ; Ansonsten alle Zeichen ausser letztem lesen
bra sak_empty_buf
sak_start_chk
ldab #LCDDELAY
stab ui_timer ; Timer setzen
sak_loop
ldab ui_timer ; Timer abgelaufen?
beq sak_end ; Dann Fehler ausgeben
jsr check_inbuf ; Ist was im Ack Buffer?
tsta
bne sak_getanswer ; Ja, dann nachsehen was es ist
swi ; Nix im Puffer - dann erstmal Taskswitch machen
bra sak_loop ; nochmal nachsehen
sak_getanswer
jsr sci_read ; Zeichen holen
cmpb #$7F ; Fehler? (Es wurde eine Taste gedrückt)
bne sak_chk_cmd
bsr sci_read_cmd ; Ja, dann Kommando lesen und in Puffer für Menü speichern
bra sak_end
sak_chk_cmd
tsx
cmpb 1,x ; Empfangenes Zeichen = gesendeten Zeichen?
beq sak_ok ; Ja, dann zurück
cmpb #$74 ; auf 'Input lock' prüfen
beq sak_unlock
jsr check_inbuf ; Noch Zeichen im Puffer?
tsta
bne sak_getanswer ; Ja, dann nochmal Vergleich durchführen
bra sak_end ; Ansonsten Ende mit Fehlermeldung
sak_ok
tsx
clr 0,x ; Alles ok, A=0 => kein Fehler
sak_end
pula
pulb
rts
sak_unlock
ldab #$75 ; Kleiner Hack um bei Fehler der als "Keylock an" interpretiert wurde
ldaa #'p' ; Diesen wieder zu deaktivieren
jsr putchar
bra sak_end ; Ende mit Fehlermeldung
;****************************
; S C I R E A D C M D
;****************************
;
; Parameter : B - Kommando / Eingabe Byte
;
; Returns : nothing
;
; required Stack Space : 9
;
;
sci_read_cmd
jsr sci_read ; Zeichen holen
pshb
src_empty_buf
jsr sci_rx
tsta
beq src_empty_buf ; Solange Zeichen lesen bis Puffer leer ist
pulb ; Zeichen zurückholen
jsr sci_tx_w ; Bestätigung senden
jsr men_buf_write ; Eingabe in Menü Puffer ablegen
rts
;****************************
; S C I T R A N S C M D
;****************************
;
; Parameter : none
;
; Returns : none
;
;
sci_trans_cmd
pshb
psha
pshx
jsr sci_rx ; Zeichen holen
tsta
bne stc_end ; Falls nichts vorhanden - Ende
stc_clear_buf
cmpb #$20 ; Werte >= $20 sind keine Eingaben
bcc stc_end
jsr check_inbuf ; Prüfen wieviele Byte im Input Speicher sind
beq stc_ack ; Wenn das letzte gerade gelesen wurde, ACK senden
jsr sci_read ; nächstes Zeichen lesen
; TODO: Handle collision between ack & next repetition
; Possible solution: Discard any char for the menu buffer arriving within the next 2 ms
bra stc_clear_buf ; loop
stc_ack
jsr sci_tx_w ; Sonst Bestätigung senden
jsr men_buf_write ; und Eingabe in Menü Puffer ablegen
stc_end
pulx
pula
pulb
rts
;****************************
; M E N B U F W R I T E
;****************************
;
; Parameter : B - Kommando / Eingabe Byte
;
; Returns : nothing
;
; changed Regs: A,B,X
;
; Required Stack Space : 2
;
men_buf_write
tba
ldab io_menubuf_w ; Zeiger auf Schreibadresse holen
incb ; prüfen ob Puffer schon voll
andb #io_menubuf_mask ; maximal 15 Einträge
cmpb io_menubuf_r ; Lesezeiger schon erreicht?
beq mbw_end ; Overrun Error, Zeichen verwerfen
ldab io_menubuf_w ; Zeiger erneut holen
ldx #io_menubuf ; Basisadresse holen
abx ; beides addieren -> Schreibadresse bestimmen
staa 0,x ; Datenbyte schreiben
incb ; Zeiger++
andb #io_menubuf_mask ;
stab io_menubuf_w ; und speichern
mbw_end
rts
;
;************************************************
;
;************************
; P U T C H A R
;************************
;
; Putchar Funktion, steuert das Display an.
;
; Parameter : A - Modus
; 'c' - ASCII Char, Char in B (ASCII $20-$7F, $A0-$FF = char + Blink)
; 'x' - unsigned int (hex, 8 Bit)
; 'd' - unsinged int (dezimal, 8 Bit) (0-99, value is printed with leading zero)
; 'u' - unsinged int (dezimal, 8 Bit)
; 'l' - longint (dezimal, 32 Bit)
; 'p' - PLAIN, gibt Zeichen unverändert aus, speichert es NICHT im Puffer
; Anwendung von 'p' : Senden von Display Befehlen (Setzen des Cursors, Steuern der LEDs, etc.)
;
;
; B - Zeichen in Modus c,x,u,p,d
; Anzahl nicht darzustellender Ziffern in Modus 'l' (gezählt vom Ende! - 1=Einer, 2=Zehner+Einer, etc...)
;
; X - Pointer auf longint in Modus L
;
; Stack - Longint in Modus l
;
;
; Ergebnis : nothing
;
; changed Regs: A,B,X
;
; changed Mem : CPOS,
; DBUF,
; Stack (longint)
;
; required Stack Space : 'c' - 15
; 'd' - 24
; 'u' - 23
; 'l' - 33
; 'x' - 23
; 'p' - 15
; jeweils +15 bei Keylock
;
putchar
#ifdef SIM
rts
#endif
cmpa #'u'
bne pc_testdecd
jsr uintdec
jmp pc_end
pc_testdecd
cmpa #'d'
bne pc_testlong
jsr uintdecd
jmp pc_end
pc_testlong
cmpa #'l'
bne pc_testlong_ind
jsr ulongout
jmp pc_end
pc_testlong_ind
cmpa #'L'
bne pc_testhex
clra
jsr decout
jmp pc_end
pc_testhex
cmpa #'x'
bne pc_testchar
jsr uinthex
jmp pc_end
pc_testchar
cmpa #'c'
bne pc_testplain
jmp pc_char_out
pc_testplain
cmpa #'p'
bne pc_to_end
jmp pc_ext_send2 ; Plain - sende Bytevalue wie erhalten
pc_to_end
jmp pc_end ; unsupported mode, abort/ignore
pc_char_out ; ASCII character in B
ldaa cpos ; Cursorposition holen
cmpa #8 ; Cursorpos >=8?
bcc pc_end ; Dann ist das Display voll, nix ausgeben (geht auch viel schneller)
jsr pc_cache ; Prüfen ob Zeichen schon an dieser Position geschrieben wurde
tsta ; Wenn ja,
beq pc_end ; dann nichts ausgeben
jsr store_dbuf ; Zeichen in Displaybuffer speichern (ASCII)
;pc_convert_out
tba ; save character to print
andb #~CHR_BLINK ; exclude Blink Bit
subb #$20 ; ASCII chars <$20 not supported
pshb ; save index
psha ; save character to print
clra ; HiByte = 0
lsld ; Index für Word Eintrüge berechnen
addd #char_convert ; Basisadresse hinzufügen
xgdx
ldd 0,x ; D=Eintrag in char_convert Tabelle
xgdx
pulb ; restore character to print
andb #CHR_BLINK ; check if should be printed blinking
xgdx
beq pc_sendchar ; if not, print plain
tsta ; check if it is an extended or a single char
beq pc_blink_single
oraa #$10 ; include blink bit in extended char code
bra pc_sendchar
pc_blink_single
orab #$10 ; include blink bit in single char code
pc_sendchar
pshb
psha ; Tabellenzeichen merken
tsta
beq pc_single ; Zeichencode mit 1 Bytes?
tab
pc_double
jsr sci_tx_w ; Zeichen senden
jsr sci_ack ; Auf Bestätigung warten
tsta ; Zeichen erfolgreich gesendet?
bne pc_double ; Wenn nicht, nochmal senden
tsx
ldab 1,x ; 2. Byte vom Tabelleneintrag holen
pc_single ; Ausgabe von Zeichencodes mit 1 Byte
jsr sci_tx_w ; send char from table
jsr sci_ack ; Auf Quittung warten
tsta ; Erfolgreich gesendet?
bne pc_single ; Nein? Dann nochmal probieren
pula ; gemerkten Tabelleneintrag holen
ins ; lower char aus Tabelle wird nicht mehr benötigt,
tab ; Blink Status ($4x / $5x) aber schon
orab #$10
cmpb #$5D ; War Byte 1 = $4D oder $5D?
beq pc_extended ; dann müssen wir noch ein $4E Char senden
pulb ; gemerkten Index vom Stack löschen
bra pc_end
pc_extended
anda #$10 ; Blink Bit isolieren
ldx #e_char_convert
pulb ; gemerkten index vom Stack holen
abx ; Tabelle indizieren
ldab 0,x ; extended character holen
pshb ; Character sichern
adda #$4E ; Extended Zeichen senden, zu Blink Bit addieren
tab ; nach B transferieren
pc_ext_send1
jsr sci_tx_w ; send char
jsr sci_ack ; Bestätigen lassen
tsta
bne pc_ext_send1 ; nochmal senden, falls erfolglos gesendet
pulb ; Character senden
pc_ext_send2
jsr sci_tx_w ; send char
jsr sci_ack ; Echo Char lesen
tsta ; bei Fehler
bne pc_ext_send2 ; wiederholen
pc_end
rts
pc_terminal
jsr sci_tx
jmp pc_end
;******************
; P C C A C H E
;
; Putchar Subroutine
;
; Funktion zur Beschleunigung der Displayausgabe
; Ãberspringt Zeichen, die schon auf dem Display vorhanden sind
; Falls ein Unterschied zwischen vorhandenem und zu schreibenden Zeichen
; auftritt, wird der Cursor von dieser Funktion korrekt positioniert
;
; Parameter : B - Zeichen (ASCII)
;
; Ergebnis : A - 0 = Zeichen überspringen
; 1 = Zeichen ausgeben
;
pc_cache
pshb
pshx
tba ; Zeichen nach A
ldx #dbuf
ldab cpos ; Cursorposition holen
abx ; Zeichen unter dem Cursor addressieren
cmpa 0,x ; Mit auszugebenden Zeichen vergleichen
beq pcc_same ; Wenn es gleich ist, Zeichen nicht ausgeben
ldaa pcc_cdiff_flag ; Unterscheidet sich Cursorposition in CPOS von tatsächlicher Cursorposition?
anda #CDIFF_FLAG
beq pcc_diff ; Nein, dann weitermachen - Returnvalue = 'Zeichen ausgeben'
ldaa #'p'
addb #$60 ; $60 zu Cursorposition addieren -> Positionierungsbefehl erzeugen
jsr putchar ; Cursor korrekt positionieren
aim #~CDIFF_FLAG, pcc_cdiff_flag ; clear flag, cursor positions match