-
Notifications
You must be signed in to change notification settings - Fork 0
/
004_hex-print.s
145 lines (112 loc) · 3.22 KB
/
004_hex-print.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
; the following code will print a number on the screen, in base 16.
; one can easily change both the message and the number on lines
; 60 and 61 respectively.
; ports of the 65C22 versatile interface adapter.
PORTB = $6000 ; port B of the versatile interface.
PORTA = $6001 ; port A of the versatile interface.
DDRB = $6002 ; port B is controlled by DDRB at 6002.
DDRA = $6003 ; port A is controlled by DDRA at 6003.
; hardware uses top 3 bits of PORTA to control the LDC display. PORTA ~ EWS*****.
E = %10000000 ; enables the LCD display for control.
RW = %01000000 ; 0 to write, 1 to read.
RS = %00100000 ; 0 to access Instruction Register (IR), 1 for Data Register (DR).
.org $8000
;; starting point of the program, resets the internals of the CPU and interface for proper use.
reset:
; initialize the processor.
ldx #$ff
txs ; set the stack to being #ff.
; initialize the LCD.
lda #%11111111 ; set all pins on port B to output.
sta DDRB
lda #%11100000 ; set top 3 pins on port A to output.
sta DDRA
lda #%00111000 ; set 8-bit mode; 2-line display; 5x8 font
jsr lcd_instruction
lda #%00001110 ; display on; cursor on; blink off
jsr lcd_instruction
lda #%00000110 ; increment and shift cursor; don't shift display
jsr lcd_instruction
lda #$00000001 ; clear display
jsr lcd_instruction
; print "num = 0x" on the LCD.
ldx #0
print_head:
lda head_of_msg,x
beq print_number
jsr print_char
inx
jmp print_head
; print the number.
print_number:
lda number + 1 ; print MS bits in little endian.
jsr print_byte
lda number ; print LS bits.
jsr print_byte
; end of program.
loop:
jmp loop
head_of_msg: .asciiz "num = 0x" ; head of the message.
number: .word $9876 ; the number to print on the LCD.
;; print in hex the byte in A.
print_byte:
pha ; save the argument in S.
ror ; roll to get the 4 MS bits.
ror
ror
ror
and #%00001111 ; mask the other bits.
tax ; transfer the index in X.
lda digits,x ; print the character.
jsr print_char
pla ; get back the argument.
and #%00001111 ; mask the MS bits.
tax ; transfer index and print.
lda digits,x
jsr print_char
rts
digits: .asciiz "0123456789abcdef" ; the list of all possible hexadecimal digits.
;; wait for the LCD display's busy flag to go low.
lcd_wait:
pha
lda #%00000000 ; Port B is input.
sta DDRB
lcdbusy:
lda #RW
sta PORTA
lda #(RW | E)
sta PORTA
lda PORTB
and #%10000000
bne lcdbusy
lda #RW
sta PORTA
lda #%11111111 ; Port B is output.
sta DDRB
pla
rts
;; send an instruction to the LCD monitor.
lcd_instruction:
jsr lcd_wait
sta PORTB
lda #0 ; clear RS/RW/E bits.
sta PORTA
lda #E ; set E bit to send instruction.
sta PORTA
lda #0 ; clear RS/RW/E bits.
sta PORTA
rts
;; print a character to the LCD monitor.
print_char:
jsr lcd_wait
sta PORTB
lda #RS ; Set RS; Clear RW/E bits
sta PORTA
lda #(RS | E) ; Set E bit to send instruction
sta PORTA
lda #RS ; Clear E bits
sta PORTA
rts
.org $fffc
.word reset
.word $0000