-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsysmon65.65s
More file actions
3523 lines (3109 loc) · 174 KB
/
sysmon65.65s
File metadata and controls
3523 lines (3109 loc) · 174 KB
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
; MAIN FILE SYSMON65.65S
; version 2.20
; two pass symbolic assembler, dissembler and tracer
; REGB bits 0-3 are connected to LED's
; tested in Michael Kowalski 6502 Simulator - using 65C02 Code
; Programmed by Joe DiMeglio
; https://github.com/jdimeglio/6502-Monitor
; bug fixes
.OPT proc65C02,swapbin ;Michal Kowaski Simulator
.START RESET_VECTOR ;version 1.3.2
.IO_WND 80,25 ;{set TAB size to 4 in editior}
;------------------------------------------------------------------------
;tricks to save a couple bytes
;------------------------------------------------------------------------
SKIP2BYTES .MACRO
.DB $2C ;cheat to skip two bytes
.ENDM
SKIP1BYTE .MACRO
.DB $42
.ENDM
;------------------------------------------------------------------------
; Compiler Options/Directives
;------------------------------------------------------------------------
BRKAS2 = 0 ;Add a second BRK byte
MYWYM = 0 ;has MYWYM Board settings/Chips
LCD_ROUTINES = 0 ;Compile with LCD 16x2 lines
SYMON = 1 ;used for SYMON to define CIA and VIA
ROM_LIBRRAY = 1 ;adds ROM library to assembler
.INCLUDE "constants.65s"
*= $e000 ;ROM location
;------------------------------------------------------------------------
; Lets get going
; Cold and Warm program entry points
;------------------------------------------------------------------------
COLD JSR INIT ;Initialise assembler
WARM CLD ;WARM Reboot/startup
LDX #$FF ;just in case
TXS
JSR WRCRLF ;Print CR & LF before we do anything
LDA COLD+1
PHA
LDA COLD
PHA
STZ AUTO_FLAG ;Clear auto flag
;------------------------------------------------------------------------
; Get input line (main program loop)
;------------------------------------------------------------------------
GETLINE LDX #$00 ;Get input line (main program loop)
;reset buffer index
LDA #PROMPT ;Print the assembler prompt
JSR WRCHAR
JSR AUTONUM ;Generate line number if auto=on
.IN JSR RDCHAR ;Was a key pressed?
.found CMP #ESC ;Is it the ESC key?
BEQ .ESC ;Nope!
CMP #BS ;Back space key then?
BEQ .BS
CMP #TAB ;Is it the TAB character?
BEQ .TABS
CMP #CR ;Is it a CR then?
BEQ .CR ;Yes!
CMP #':' ;INTEL Hex loader
BNE .LF ;nope then skip
JSR CMD_INTELHEX
BRA GETLINE
.LF CMP #LF ;Is it a CR then?
BEQ .IN ;Strip LF useful for pasting code
STA IN,X ;Save new character in input buffer
JSR WRCHAR ; and display it
INX
BPL .IN ;Get next character unless its 128 characters
BRA .CANCEL ;Always taken! Too many chars.
.ESC STZ AUTO_FLAG ;Clear auto flag and therefore OFF
; .IF MYWYM
; .IF SYMON
; JSR RDCHAR ;get the unwanted arrow keys
;
; .ELSE
; ;JSR RDCHAR
; ;JSR RDCHAR
; .ENDIF
; .ENDIF
.CANCEL JSR WRCRLF ;Print CRLF
BRA GETLINE ;Always taken! Restart line
.BS JSR WRCHAR ;Process Back SPACE
DEX ;Decrement input pointer
BPL .IN ;Still positive!
INX ;Don't allow it to go negative
BRA .IN ;Always taken!
.TABS LDY #0 ;Point to 1st tab stop
.TABS_NEXT LDA TABS,Y ;It X smaller than this one?
STA COUNT
LDA #SP ;replace with SPACE probably dont need this
CPX COUNT
BCC .DOTAB ;Yes! Tab to this position
INY
CPY #NUMTABS ;Maximum number of tab stops
BCC .TABS_NEXT ;Try next!
.DOTAB STA IN,X ;Save this character
INX
JSR WRCHAR ; and WRCHAR it
CPX COUNT ;At tab stop?
BCC .DOTAB ;Not yet!
BRA .IN ;Always taken!
.CR STA IN,X ;Mark end of line now with CR
JSR UPPERCASE ;convert to upper case
JSR WRCRLF ;CR new line
JSR FIRSTNONSPC ;Find first non space
BEQ GETLINE ;End of line reached!
CMP #'0' ;Is it a line number?
BCC .NOLINE ;No!
CMP #'9'+1
BCC .LINENUM ;It is! Add it to the program
.NOLINE JSR KEYDEF ;Parse command, or line number
.CHK_ERROR LDA ERROR ;Was there an error?
BEQ .GETLINE ;Nope!
JSR PRINT_MSGS ;Print error
.GETLINE JMP GETLINE ;Stay in main program loop
.LINENUM JSR ADDLINE ;Add line to program
JMP .CHK_ERROR ;Check if an error occurred
TABS .BYTE TAB1 ;1st tab stop
.BYTE TAB2 ;2nd tab stop
.BYTE TAB3
.BYTE TAB4 ;3rd tab stop
NUMTABS = 4 ;Number of tab stops
;------------------------------------------------------------------------
; Parse command line
; IN: AC holds the command character
;------------------------------------------------------------------------
KEYDEF LDY #0 ;Find command in table
STY ERROR ;Clear error
STA CMD_CHR
.LOOP LDA .TABLE,Y
BEQ .SYNERR ;End of table! Syntax errorv
CMP CMD_CHR ;Is it this command
BEQ .FOUND ;Found our command!
INY ;Next command from table
BRA .LOOP ;Always taken!
.FOUND JSR IN_BLANK ;Get next and see if it's blank
BNE .FOUND ;A CR would have been too! Sets up X
TYA ;Point to command handler's
ASL ; address in table
TAY
LDA FUNCTIONS+1,Y ; Get the address and use it MSB first
PHA ; as return address
LDA FUNCTIONS,Y
PHA
LDY #0 ;Some commands may benefit from this
JMP NNONSPC ;Find next non space and exec cmd XR points to IN.X
.SYNERR LDA #ERR_SYN ;Exit with syntax error
STA ERROR
RTS
;------------------------------------------------------------------------
; Table of keyboard commands
;
;------------------------------------------------------------------------
.TABLE .BYTE 'A' ;Auto line numbering
.BYTE 'B' ;Break command
.BYTE 'C' ;Copy command
.BYTE 'D' ;Dissassembler
.BYTE 'E' ;Erase command
.BYTE 'F' ;Fill Command - future
.BYTE 'G' ;GO command - future
.BYTE 'H' ;Hunt Command - future
.BYTE '?' ;Help command
.BYTE 'I' ;ASCII Dump
.BYTE 'L' ;List command
.BYTE 'M' ;Memory command
.BYTE 'N' ;New command
.BYTE 'O' ;Old command
.BYTE 'R' ;Renumber command
.BYTE 'S' ;Start assembling
.BYTE 'T' ;Trace code
.BYTE 'V' ;Value command
.BYTE 'W' ;Display registers
.BYTE 'Y' ;memory configuraion
.BYTE 'Z' ;Clear Screen
.BYTE $13 ;[CNTL-S] - clean code
.BYTE 'J' ;Edit Memory
.BYTE "K" ;Watch register
.BYTE '@' ;User commands
CMD_BRK .BYTE 0 ;End of table & BRK
;------------------------------------------------------------------------
; Table of commands
; RTS will a +1 to the address
;------------------------------------------------------------------------
FUNCTIONS .WORD CMD_AUT-1 ;Auto line numbering
.WORD CMD_BRK-1 ;Break command
.WORD CMD_COP-1 ;Copy command
.WORD CMD_DISSASSEMBLER-1 ;Dissassembler
.WORD CMD_ERASE-1 ;Erase command
.WORD CMD_FILL-1 ;Fill memory
.WORD CMD_XEC-1 ;eXecute command
.WORD CMD_HUNT-1 ;hunt command
.WORD CMD_HLP-1 ;Help command
.WORD CMD_ASCIIDUMP-1 ;ASCII DUMP
.WORD CMD_LST-1 ;List command
.WORD CMD_MEMORY_DUMP-1 ;Memory command
.WORD CMD_NEW-1 ;New command
.WORD CMD_OLD-1 ;Old command
.WORD CMD_REN-1 ;Renumber command
.WORD CMD_ASM-1 ;Start assembling
.WORD CMD_TRACE-1 ;Trace Code
.WORD CMD_VAL-1 ;Value command
.WORD CMD_SHOWREG-1 ;Display registers
.WORD CMD_MEM-1 ;Memory command
.WORD CLS-1 ;Clrscreen command
.WORD CMD_CLEAN_CODE-1 ;Clean up the Code
.WORD CMD_EDIT_MEMORY-1 ;edit memory
.WORD CMD_WATCH-1 ;add whatch to Tracer
.WORD CMD_USERKEYS-1 ;Allows users to add more keys after @
;----------------------------------------------------------------------------------------
; Allows users to add more keys after @
;----------------------------------------------------------------------------------------
CMD_USERKEYS JMP (USERKEYDEF)
;----------------------------------------------------------------------------------------
; cancel in the Assembler editor
;----------------------------------------------------------------------------------------
CMD_ESC STZ AUTO_FLAG ;Clear auto flag and therefore OFF
.CANCEL LDA #BELL ;play bell
JSR WRCHAR
JMP WRCRLF ;Print CRLF
;----------------------------------------------------------------------------------------
;Intel HEX loader
;----------------------------------------------------------------------------------------
.INCLUDE "INTELHEX.65s"
;------------------------------------------------------------------------
;Bump Address by AC ie: SRCE variable add it by AC
;------------------------------------------------------------------------
BUMPSRCE CLC
ADC SRCE
STA SRCE
BCC .BUMPSRCE
INC SRCE+1
.BUMPSRCE RTS
;------------------------------------------------------------------------
;Instruction display - orginal code seems to come from MOS
;------------------------------------------------------------------------
INSTDSP TAY ;Save op code
LSR ;* Even/odd test
BCC .IEVEN
ROR ;* Test B1
BCS .ERR ;XXXXXX11 instr invalid
;CMP #$A2
;BEQ ERR ;10001001 instr invalid
AND #$87 ;Mask 3 bits for address mode
;ORA #$80 ;* add indexing offset
.IEVEN LSR ;* LSB into carry for
TAX ;Left/right test below
LDA MODE,X ;Index into address mode table
BCC .RTMODE ;If carry set use LSD for
LSR ;* print format index
LSR
LSR ;If carry clear use MSD
LSR
.RTMODE AND #$0F ;Mask for 4-bit index
BNE .GETFMT ;$0 for invalid opcodes
.ERR LDY #$FC ;Substitute $FC for invalid op,
LDA #$00 ;set print format index to 0
.GETFMT TAX
LDA MODE2,X ;Index into print format table
STA SAVE_Y ;Save for address field format
AND #$03 ;Mask 2-bit length. 0=1-byte
STA LENG ;* 1=2-byte, 2=3 byte
TYA ;* op code
JSR GETMNE ;Lookup the mnemonic
LDY #$00
PHA ;Save mnemonic table index
.PROP LDA (SRCE),Y
JSR WR2HEX
LDX #$01
.PROPBL JSR WRBL2
CPY LENG ;Print instr (1 to 3 bytes)
INY ;* in a 12-character field
BCC .PROP
LDX #$03 ;char count for mnemonic print
STX PRFLAG ;So EXPMNE prints the mnemonic
CPY #$04
BCC .PROPBL
PLA ;Recover mnemonic index
TAX
JSR EXPMNE ;Expand the Memonic
JSR WRBLNK ;Output 3 blanks
LDY LENG
LDX #$06 ;Count for 6 print format bits
.PPADR1 CPX #$03
BEQ .PPADR5 ;If X=3 then print address val
.PPADR2 ASL SAVE_Y ;Test next print format bit
BCC .PPADR3 ;If 0 don't print
LDA CHAR1-1,X ; * corresponding chars
JSR WRCHAR ;Output 1 or 2 chars
LDA CHAR2-1,X ;* (If char from char2 is 0,
BEQ .PPADR3 ;* don't output it)
JSR WRCHAR
;LDA UNDEF
;JSR WRDECI
.PPADR3 DEX
BNE .PPADR1
STX PRFLAG ;reset flag to 0
RTS ;Return if done 6 format bits
.PPADR4 DEY
BMI .PPADR2
JSR WR2HEX ;Output 1- or 2-byte address
.PPADR5 LDA SAVE_Y
CMP #$E8 ;Handle rel addressing mode
LDA (SRCE),Y ;Special print target adr
BCC .PPADR4 ;* (not displacement)
.RELADR JSR PCADJ3 ;PCL,H + DISPL + 1 to A,Y
TAX
INX ;adjust
BNE PRNTYX ;* +1 to X,Y
INY
PRNTYX TYA ;falls through
;------------------------------------------------------------------------
;print AX as a HEX word
;------------------------------------------------------------------------
PRNTAX JSR WR2HEX ;Print target adr of branch (DUPLICATE FUNCTION to WRWORDAY)
PRNTX TXA ; * and return
JMP WR2HEX
;------------------------------------------------------------------------------------------
;PC Adjust - Program counter
;------------------------------------------------------------------------------------------
PCADJ SEC
PCADJ2 LDA LENG ;0=1-byte, 1=2-byte, 2=3-byte
PCADJ3 LDY SRCE+1
TAX ;* test displ sign (for rel
BPL .PCADJ4 ;* branch). Extend neg
DEY ;* by decrementing PCH
;SEC ;* by incrementing PCL
;CLC
.PCADJ4 ADC SRCE
BCC .RTS ;PCL+LENGTH (or displ) + 1 to A
INY ;* carry into Y (PCH)
.RTS RTS
;------------------------------------------------------------------------
; Expand Mnemic
; copy the 2 chars at R/LMNETB,X
; into LMNE and RMNE, and expand
; into 3 chars at MNE to MNE+2
;------------------------------------------------------------------------
EXPMNE LDA LMNETB,X ;Expand Mnemic
STA PARM1
LDA RMNETB,X
STA PARM1+1
LDX #$00
.NEXT LDA #$00
LDY #$05 ;5 bits of used
.LOOP ASL PARM1+1 ;across 2 bytes
ROL PARM1 ;expand and extra
ROL
DEY
BNE .LOOP
ADC #'A'-1
;STA MNE,X
LDY PRFLAG ;check if print to screen
BEQ .SKIP
JSR WRCHAR ;print the mnemonic as well
.SKIP INX
CPX #$03
BNE .NEXT
RTS
;------------------------------------------------------------------------
;Attached address to Whatch in Trace
;------------------------------------------------------------------------
CMD_WATCH JSR GET_VAL ;Get the line number value
BNE .RTS ;An error occurred!
STY WHATCH ;Get first whatch address
STA WHATCH+1
LDA IN,X ;Does the increment follow?
CMP #','
BNE .RTS ;Nope!
INX
JSR GET_VAL ;Get send Whatc
BNE .RTS ;An error occurred!
STY WHATCH+2 ;store second address
STA WHATCH+3
LDA IN,X ;Does the increment follow?
CMP #','
BNE .RTS ;Nope!
INX
JSR GET_VAL ;Get send Whatc
BNE .RTS ;An error occurred!
STY WHATCH+4 ;Get 3rd address
STA WHATCH+5
.RTS RTS
;------------------------------------------------------------------------
;Hunt F start end value
;------------------------------------------------------------------------
CMD_HUNT JSR GET_VAL ;Fill Memory
STY SRCE ;Get start address
STA SRCE+1
INX
JSR GET_VAL ;FILL end address
STY DEST
STA DEST+1
INX
JSR GET_VAL ;FILL value
STY CHAR
SEC ;find length add +1
LDA DEST
SBC SRCE
STA LENG
LDA DEST+1
SBC SRCE+1
STA LENG+1
TYA ;the value
LDY LENG+1
BEQ .partpg ;compare partpage
LDY #00 ;another way is keep y=0 and increment
.fullpg CMP (SRCE),Y
BNE .skip1 ;probably should be write error
JSR DISPLAY_ADDR
.skip1 INY
BNE .fullpg
INC SRCE+1
DEC LENG+1 ;are we done
BNE .fullpg
.partpg LDY LENG
.loop1 CMP (SRCE),Y
BNE .skip2
;savey
;savya
;add + y to A
;better of inc source until equals dest
;probably should be write error
JSR DISPLAY_ADDR
LDA CHAR ;get the value
.skip2 DEY
BNE .loop1
;STA (SRCE),Y ;last byte
RTS
;------------------------------------------------------------------------
;ASCII DUMP
;------------------------------------------------------------------------
CMD_ASCIIDUMP JSR GET_EXPRES ;Get Source aka get expression
BNE .CONT
STY SRCE
STA SRCE+1
.CONT LDA #$42
STA COUNT
LDY #$14
.NEXTLINE PHY
JSR DISPLAY_ADDR ; display address format
JSR ASCII_DUMP
JSR WRCRLF
LDA #42
JSR BUMPSRCE ; Add to SRCE
PLY
DEY
BNE .NEXTLINE
STZ ERROR ; No Error
RTS
;------------------------------------------------------------------------
;ASCII DUMP one line
;------------------------------------------------------------------------
ASCII_DUMP LDA #'/' ;ASCII DUMP - Dumps ASCII onto the screen
JSR WRCHAR
LDY #$00
.NEXTCHAR1 LDA (SRCE),y
CMP #$1f
BCC .NOTASCII
CMP #$7f
BCS .NOTASCII
BRA .WRITE
.NOTASCII LDA #'.'
.WRITE JSR WRCHAR
INY
CPY COUNT
BNE .NEXTCHAR1
RTS
;------------------------------------------------------------------------
; display address without the $ A=MSD y=LSB
;------------------------------------------------------------------------
DISPLAY_ADDR LDA #'.'
JSR WRCHAR
LDA #':'
JSR WRCHAR
DISPLAY_ADDR_B LDA #SP ;basic version
JSR WRCHAR
LDA SRCE+1
LDY SRCE
JSR WRWORDAY ;print address AY
LDA #SP ;TABS HERE
JSR WRCHAR
JMP WRCHAR ;return to caller
;------------------------------------------------------------------------
;Memory DUMP one line
;------------------------------------------------------------------------
CMD_MEMORY_DUMP JSR GET_EXPRES ;DUMPS MEMORY TO THE SCREEN
BNE .CONT
STY SRCE
STA SRCE+1
.CONT JSR CLS ;Cursor top left
JSR STRING
.ASCII " _____ _____ _____",CR,LF
.ASCII " | | __| |",CR,LF
.ASCII " | | | | __| | | |",CR,LF
.ASCII " |_|_|_|_____|_|_|_|",CR,LF, EOS
JSR DMPGR ;draw the 00 01 02 03 etc etc
JSR DRAWLINECR ;draw line
DRAWMEM_DRAW LDY #$10 ;lines to draw = 1 page of memory
LDX #04 ;divided by 4
.NEWLINE PHY
JSR DISPLAY_ADDR
LDY #$00
.DUMP LDA (SRCE),y ;SCAN_ESC
JSR WR2HEX
LDA #SP
JSR WRCHAR
DEX
BNE .SKIPSP
LDX #04 ;4 coloumns of 4 words to display
JSR WRCHAR ;then add a 2nd space
.SKIPSP INY
CPY #$10
BNE .DUMP
JSR WRSPACE
STY COUNT
JSR ASCII_DUMP ;draw ASCII dump end of the row
JSR WRCRLF ;new line
LDA #$10
JSR BUMPSRCE ;Add to SRCE for next 16 bytes
PLY
JSR SCAN_ESC ;Scan for Escape
BEQ EXIT ;Z=1 Escape pressed
DEY
BNE .NEWLINE
STZ ERROR
EXIT RTS
;------------------------------------------------------------------------
;Move Cursor to position from SAVX,SAVY
;
; X table lookup & Y+2
;------------------------------------------------------------------------
MOVETOCUROR LDY SAVX
LDA XCORDINATE,Y
TAX
MOVETOCUROR_Y LDY SAVY ;adjust Y down by 2
INY ;hard coded 2 rows
INY
JSR GOTOXY ;move cursor
RTS
;------------------------------------------------------------------------
;Draw Screen
;
;
;------------------------------------------------------------------------
DRAW_SCREEN LDA DEST ;Refresh WHOLE screen
LDY DEST+1 ;set Source of the page to be drawn
STA SRCE
STY SRCE+1 ;clear screen & know where X&Y area
JSR CMD_MEMORY_DUMP
RTS
;------------------------------------------------------------------------
;EDIT MEMORY one line
; DEST start of Memory Page to be edited
; SAVY,SAVX = X,Y location for memory to be edited
;------------------------------------------------------------------------
CMD_EDIT_MEMORY JSR GET_EXPRES ;edit memory
BNE .CONT1
STY SRCE ;store source
STA SRCE+1
.CONT1 LDY SRCE
LDA SRCE+1
.SAVE_DEST STY DEST ;save source in dest as start of page
STA DEST+1
.CONT2 STZ SAVY ;1st position for memory
STZ SAVX
JSR DRAW_SCREEN ;draw full screen
SCAN_KEYBOARD JSR CHECK_WIN_FRAME
JSR MOVETOCUROR ;move cursor from SAVX,SAVY
JSR RDCHAR ;read keyboard
CMP #ESC ;ESCAPE for exit
BEQ .EXIT ;Exit
.CHECKRIGHT CMP #RIGHTARROW ;Check right key
BNE .CHECKLEFT
INC SAVX
BRA SCAN_KEYBOARD
.CHECKLEFT CMP #LEFTARROW
BNE .CHECKDOWN
DEC SAVX ;one byte of RAM
BRA SCAN_KEYBOARD
.CHECKDOWN CMP #DOWNARROW
BNE .CHECKUP
INC SAVY ;Update RAM Cordinates
BRA SCAN_KEYBOARD
.CHECKUP CMP #UPARROW
BNE .DIGITCHECK
DEC SAVX
BRA SCAN_KEYBOARD
.DIGITCHECK CMP #CR ;Was CR pressed
BNE SCAN_KEYBOARD
JSR COMMANDLINE
LDA #ADDR_MSG
JSR PRINT_MSGS
JSR RD2HEX
STA HEXVAL ;save binary value that was inputted
LDA SAVY ;calculate Memory address
ASL ;multiple by 16
ASL
ASL
ASL
STA TEMP1 ;now TEMP1=SAVY*16 (y memory index)
LDA SAVX
CLC
ADC TEMP1 ;Y*16+X
TAY ;A= index to memory location
LDA HEXVAL
STA (DEST),Y
JSR COMMANDLINE_CLR
BRA SCAN_KEYBOARD ;done - go back and start again
.EXIT LDY #18 ;return cursor to bottom of screen
LDX #00
JSR GOTOXY
EXIT_WIN_FRAME RTS
;------------------------------------------------------------------------
; defined Command line row 20
;------------------------------------------------------------------------
COMMANDLINE LDY #20 ;return cursor to bottom of screen
LDX #00
JSR GOTOXY
RTS
;------------------------------------------------------------------------
;clear row 20 (31 spaces)
;------------------------------------------------------------------------
COMMANDLINE_CLR JSR COMMANDLINE
JSR STRING
.DB $FF ;draw space 31 characters
RTS
;------------------------------------------------------------------------
;Dump Offsets to Screen - ;check if within Window Frame
;------------------------------------------------------------------------
CHECK_WIN_FRAME LDX SAVX ;Load up X,Y
LDY SAVY
CPX #00 ;did it go neg
BPL .CHECK_X_MAX
STZ SAVX
DEY
DEC SAVY ;go back a screen load
BRA .CHECK_Y_MIN ;have to jump X=$FF here
.CHECK_X_MAX CPX #16 ;X limit
BCC .CHECK_Y_MAX
STZ SAVX ;New Line eg CR
INY
INC SAVY ;LF eqivilent
.CHECK_Y_MAX CPY #16 ;Y screen limit
BCC .CHECK_Y_MIN ;Not exceed then check Y min
DEC SAVY ;adjust Y + $FF bytes forward
LDA DEST
CLC
ADC #$10
STA DEST
BCC .SKIP_ADC
INC DEST+1
.SKIP_ADC JMP DRAW_SCREEN ;redraw screen & then RTS
.CHECK_Y_MIN CPY #00
BPL EXIT_WIN_FRAME
STZ SAVY
LDA DEST ;sbc 1 page
SEC
SBC #$10
STA DEST
BCS .SKIP_SBC
DEC DEST+1
.SKIP_SBC JMP DRAW_SCREEN ;redraw screen & then RTS
;.EXIT RTS ;save a byte
;------------------------------------------------------------------------
;Dump Offsets to Screen
;------------------------------------------------------------------------
DMPGR LDX #XEDGE ;Send 9 [SPACE] to terminal
JSR WRBL2
LDY #$00
LDX #$04 ;Initialize line counter
.LOOP1 TYA ;Send "00" thru "0F", separated by 2 [SPACE], to terminal
JSR WR2HEX
JSR WRSPACE
DEX
BNE .SKIPSP
LDX #04
JSR WRSPACE
.SKIPSP INY
CPY #$10
BNE .LOOP1
RTS ;Done DMPGR or MEMDMP subroutine, RETURN
;------------------------------------------------------------------------
; Move a part of memory down (to delete or shorten source lines)
;
; SRCE 2 Address of source data (destroyed)
; DEST 2 Address of destination data (destroyed)
; LENG 2 Holds the number of bytes to move
;------------------------------------------------------------------------
MOV_DOWN LDY #0 ;Clear index in 256 byte blocks
LDX LENG+1 ;Get number of blocks to be moved
BEQ .LAST ;Move last (partial) block
.LOOP1 LDA (SRCE),Y ;Move this byte
STA (DEST),Y
INY ;Point to next byte in block
BNE .LOOP1 ;Block not done yet!
INC SRCE+1 ;Point to next block
INC DEST+1
DEX ;Count down blocks
BNE .LOOP1 ;Not all blocs done yet!
.LAST LDX LENG ;Count remainder of last block
BEQ .EXIT ;Oh, there is no remainder!
.LOOP2 LDA (SRCE),Y ;Move this byte
STA (DEST),Y
INY ;Point to next byte in last block
DEX ;Count down the bytes
BNE .LOOP2 ;Last block not done yet!
.EXIT RTS
;------------------------------------------------------------------------
; Move a part of memory up (to make room for new or longer source line)
;
; SRCE 2 Address of source data
; DEST 2 Address of destination data
; LENG 2 Holds number of bytes to move
;
;------------------------------------------------------------------------
MOV_UP LDX LENG+1 ;We have started the move at the
CLC ;end otherwise we risk
TXA ;overwriting the source
ADC SRCE+1
STA SRCE+1 ;So add Length-High to source and
CLC ;destination address
TXA
ADC DEST+1
STA DEST+1
INX ;Allow BNE to signal the end
LDY LENG
BEQ .PAGE ;Only entire pages to be moved!
DEY
BEQ .PART ;Move last, partial, page first!
.LOOP1 LDA (SRCE),Y ;Move one entire page
STA (DEST),Y
DEY ; backwards
BNE .LOOP1 ;Page not done yet
.PART LDA (SRCE),Y ;Move first byte of page too
STA (DEST),Y
.PAGE DEY
DEC SRCE+1 ;Decrement source and destination
DEC DEST+1
DEX
BNE .LOOP1 ;Move all pages!
RTS
;------------------------------------------------------------------------
; Print error c=1 means its ERROR messages
;------------------------------------------------------------------------
PRINT_MSGS LDY ERROR
BNE ERRORMSGS ;normal string
PRINT_ERR LDY #<TEXT1 ;Error texts
STY SRCE
LDY #>TEXT1
STY SRCE+1
TAY ;index to message string
BRA PRINT_SRCE
ERRORMSGS LDA #<TEXT ;noramal texts
STA SRCE
LDA #>TEXT
STA SRCE+1
JSR PRINT_SRCE ;Print 3 characters
LDY #0 ;Save A
STY ERROR ;Clear the error now
PRINT_SRCE LDA (SRCE),Y ;Get character (also GLobal Print)
PHA
AND #%01111111
JSR WRCHAR ; and print it
INY ;check if it exceed 127
PLA
BPL PRINT_SRCE ; is bit=8 =1
RTS
;------------------------------------------------------------------------
; Error Messages - TODO - Can be impoved
;------------------------------------------------------------------------
TEXT .ASCII " ERROR",CR,LF + $80
PNTR_ERR_SYN .ASCIS " :SYNTAX" ;Syntax error
PNTR_ERR_LBL .ASCIS " :LABEL" ;Label error / no global
PNTR_ERR_RNG .ASCIS " :INVALID RANGE" ;Range error
PNTR_ERR_MIS .ASCIS " :MISSING PARAMETER or OPERAND";Missing parameter/operand
PNTR_ERR_DIV .ASCIS " :DIVIDE by 0" ;Divide by 0 error
PNTR_ERR_MEM .ASCIS " :MEMORY FULL" ;Memory full / illegal TA
PNTR_ERR_DEF .ASCIS " :UNDEFINED LABEL" ;Undefined label
PNTR_ERR_DIR .ASCIS " :ILLEGAL DIRECTIVE" ;Illegal directive error
PNTR_ERR_OPE .ASCIS " :OPERAND" ;Operand error
PNTR_ERR_MNE .ASCIS " :MNEMONIC " ;Mnemonic error
PNTR_ERR_EXT .ASCIS " :EXTRAT DEFINATION" ;Extra definition error
PNTR_ERR_WRT .ASCIS " :UNABLE TO WRITE/READ" ;Read/Write Error
TEXT1 .ASCIS "AUTONUM ENABLE starting " ;
PNTR_ERRORS .ASCII " COMPILE ERROR(s)",CR,LF + $80
PNTR_CANCEL .ASCIS "/"
PNTR_CODE_ORG .ASCIS ".ORG ->"
PNTR_ADDR_MSG .ASCIS "addrs"
ERR_SYN = PNTR_ERR_SYN - TEXT ;index to messages
ERR_LBL = PNTR_ERR_LBL - TEXT
ERR_RNG = PNTR_ERR_RNG - TEXT
ERR_MIS = PNTR_ERR_MIS - TEXT
ERR_DIV = PNTR_ERR_DIV - TEXT
ERR_MEM = PNTR_ERR_MEM - TEXT
ERR_DEF = PNTR_ERR_DEF - TEXT
ERR_DIR = PNTR_ERR_DIR - TEXT
ERR_OPE = PNTR_ERR_OPE - TEXT
ERR_MNE = PNTR_ERR_MNE - TEXT
ERR_EXT = PNTR_ERR_EXT - TEXT
ERR_WRT = PNTR_ERR_WRT - TEXT
;standard messages
AUTOTEXT = 0 ;Flag to set aut oumbering
STR_ERRORS = PNTR_ERRORS - TEXT1
STR_CANCEL = PNTR_CANCEL - TEXT1
CODE_ORG = PNTR_CODE_ORG - TEXT1
ADDR_MSG = PNTR_ADDR_MSG - TEXT1
;------------------------------------------------------------------------
; Find next non space
; Z=1 if EOL found
;------------------------------------------------------------------------
FIRSTNONSPC LDX #0 ;Start at the begin of the line
NNONSPC LDA IN,X ;Is this a space?
CMP #SP
BNE .NOSPACE ;It is not!
INX
BRA NNONSPC ;Always taken!
.NOSPACE CMP #CR ;Set Z if we're at EOL
RTS
;------------------------------------------------------------------------
; Initialise the assembler before we can start
;------------------------------------------------------------------------
INIT CLD ;You'll never know
.IF LCD_ROUTINES
STZ WR2LCD ;Clear flag ie: write to Serial put
JSR LCD_LINIT
.ENDIF
;Memory scan
.LOOP LDA HIMEM+1 ;Stop if we run into our own code (himem +1)
CMP #>COLD ;/COLD
BEQ .THATSIT
LDA (HIMEM),Y ;See if this memory page exists
TAX ;Save original value
LDA #%01010101 ;Try this value first
JSR PROBE
BNE .THATSIT ;End of RAM!
LDA #%10101010 ;Then try this value
JSR PROBE
BNE .THATSIT ;End of RAM!
TXA ;Restore original value
STA (HIMEM),Y
INC HIMEM+1 ;Try next memory page
BPL .LOOP ;No need to proceed beyond $8000!
.THATSIT JSR SHOWMEM
LDY #$00 ;set EOR flag to zero
JMP DONEW ;Do new command (Y must be $00)
;------------------------------------------------------------------------
; Probe memory location
;------------------------------------------------------------------------
PROBE STA (HIMEM),Y ;Store this value
CMP (HIMEM),Y ;See if it was accepted
XEC_RTS RTS
;------------------------------------------------------------------------
; Get a single 16-bit value from input line
;------------------------------------------------------------------------
GET_VAL STZ NEG_FLAG ;Clear negative flag
STZ HEXVAL ;Clear end result
STZ HEXVAL+1
STZ DELIM ;Clear digit entered flag
STZ ERROR
LDA IN,X ;Read character from IN
CMP #'+' ;Is it explicit positive?
BEQ .POS ;Yes!
CMP #'-' ;Is it a negative number?
BNE .NOSIGN ;No! No prefix sign given
STA NEG_FLAG ;Set negative flag
.POS INX ;Point to next byte in IN
LDA IN,X ; and get it
.NOSIGN CMP #'0' ;Could it be a decimal number?
BCC .HEX ;Nope!
CMP #'9'+1
BCS .HEX ;Nope!
;------------------------------------------------------------------------
; Convert a decimal number to binary
;------------------------------------------------------------------------
.DECLOOP EOR #'0' ;Strip ASCII part
CMP #9+1 ;Is it still a decimal digit?
BCS .DONEG1 ;Nope!
TAY ;Save new digit
ASL HEXVAL ;Multiply previous value by 10
ROL HEXVAL+1
BCS .RANGE ;Exit with range error!
LDA HEXVAL
ASL
STA DEC_SAVE
LDA HEXVAL+1