-
Notifications
You must be signed in to change notification settings - Fork 4
/
2400bps.inc
92 lines (84 loc) · 5.82 KB
/
2400bps.inc
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
;--------------------------------------------------------------------------------------------------
; i4004 putchar and getchar functions for 2400 bps, 7 data bits, no parity, 1 stop bit
; (1/(5068000 MHz/7))*8 clocks/cycle = 11.05 µseconds/cycle
; for 2400 bps: 1000000 µseconds ÷ 2400 bits/second ÷ 11.05 µseconds/cycle = 38 cycles/bit
;--------------------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------------------
; send the character in P1 (R2,R3) to the serial port (the least significant bit of port 0)
; in addition to P1 (R2,R3) also uses P6 (R12,R13) and P7 (R14,R15)
; NOTE: destroys P1, make sure that the character in P1 is saved elsewhere!
;--------------------------------------------------------------------------------------------------
putchar: fim P7,SERIALPORT
src P7 ; address of serial port for I/O writes
ldm 0
wmp ; send the start bit
fim P7,6
isz R15,$ ; 20 cycle delay
nop
ld R2 ; get the most significant nibble of the character from R2
ral ; rotate the most significant bit into carry
stc ; set the carry bit to 1
rar ; set the most significant bit of the character (the stop bit)
xch R2 ; save the most significant nibble of the character in R2
ldm 16-8 ; 8 bits (7 data bits and 1 stop bit) to send
xch R12 ; R12 is used as the bit counter
putchar2: ld R2 ; get the most significant nibble of the character from R2
rar ; shift the least significant bit into carry
xch R2 ; save the result in R2 for next time
ld R3 ; get the least significant nibble of the character from R3
rar ; shift the least significant bit into carry
xch R3 ; save the result in R3 for next time
tcc ; transfer the carry bit to the least significant bit of the accumulator
wmp ; write the least significant bit of the accumulator to the serial output port
fim P7,3
isz R15,$ ; 26 cycle delay
isz R12,putchar2 ; do it for all 8 bits in P1
bbl 0
;-----------------------------------------------------------------------------------------
; wait for a character from the serial input port (TEST input on the 4004 CPU).
; NOTE: the serial input line is inverted by hardware before it gets to the TEST input;
; i.e. TEST=0 when the serial line is high and TEST=1 when the serial line is low,
; therefore the sense of the bit needs to be inverted in software.
; echo the received character bit by bit to the serial output port (bit 0 of port 0).
; return the 7 bit received character in P1 (R2,R3).
; in addition to P1, also uses P6 (R12,R13) and P7 (R14,R15).
;-----------------------------------------------------------------------------------------
getchar: jcn t,$ ; loop here until the start bit is detected
; the start bit has been detected, delay 1/2 bit time...
getchar4: ldm 16-8
xch R12 ; R12 holds the number of bits to receive (7 data bits and 1 stop bit);
fim P7,SERIALPORT
src P7 ; define the serial port for I/O writes
fim P7,13
isz R15,$ ; 6 cycles delay
ldm 0 ; start bit is low
wmp ; send the start bit
fim P7,12
isz R15,$
; loop here until all seven bits plus stop bit have been received...
getchar7: fim P7,7 ; delay 1 bit time
isz R15,$
nop
ldm 1 ; "0" at the TEST input will be inverted to "1"
jcn tn,getchar8a ; jump if TEST input is 1
jun getchar8b ; skip the next two instructions since the TEST input is 0
getchar8a: nop ;
ldm 0 ; "1" at the TEST input is inverted to "0"
getchar8b: wmp ; echo the inverted bit back to the serial output port
rar ; rotate the received bit into carry
ld R2 ; get the high nibble of the received character from R2
rar ; rotate received bit from carry into most significant bit of R2, least significant bit of R2 into carry
xch R2 ; save the high nibble
ld R3 ; get the low nibble of the character from R3
rar ; rotate the least significant bit of R2 into the most significant bit of R3
xch R3 ; extend register pair to make 8 bits
nop
nop
isz R12,getchar7 ; loop back until all 8 bits are read
; 7 data bits and 1 stop bit have been received, clear the the most significant bit of the most significant nibble (the stop bit)
ld R2 ; get the most significant nibble from R2
ral
clc
rar ; shift the cleared carry bit back into the most significant bit of the most significant nibble
xch R2 ; save it back into R2
bbl 0 ; return to caller