initial commit
This commit is contained in:
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# RC2014 - Quazar OLED board
|
||||||
|
|
||||||
|
This project provides MACRO-80 assembler code for `oled` program to drive OLED display for RC2014 by Quazar. It provides a Rust "script" to convert 128x32 black and white image to hex output suitable for the `oled` program.
|
||||||
|
|
||||||
|
## Compiling
|
||||||
|
|
||||||
|
```
|
||||||
|
m80 =oled.mac/z
|
||||||
|
l80 oled,oled/n/e
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```
|
||||||
|
oled
|
||||||
|
```
|
||||||
|
|
||||||
|
Now paste your image hex data as generated by `oled-to-hex`.
|
||||||
58
oled-to-hex
Executable file
58
oled-to-hex
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env -S denim
|
||||||
|
/* Cargo.toml
|
||||||
|
[package]
|
||||||
|
name = "oled-to-hex"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Anonymous"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
image = { version = "0.25.8", default-features = false, features = ["png"] }
|
||||||
|
*/
|
||||||
|
|
||||||
|
use image::GenericImageView;
|
||||||
|
use image::ImageReader;
|
||||||
|
use image::Pixel;
|
||||||
|
use std::env;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io::{Error as IoError, ErrorKind};
|
||||||
|
|
||||||
|
/// Example script description
|
||||||
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let file = env::args().skip(1).next().ok_or(IoError::new(
|
||||||
|
ErrorKind::NotFound,
|
||||||
|
"expected PNG 128x32 file path",
|
||||||
|
))?;
|
||||||
|
println!("Loading {}", file);
|
||||||
|
|
||||||
|
let img = ImageReader::open(file)?.decode()?;
|
||||||
|
let (w, h) = img.dimensions();
|
||||||
|
println!("Loaded file {}x{}", w, h);
|
||||||
|
if w != 128 && h != 32 {
|
||||||
|
return Err(Into::into(IoError::new(
|
||||||
|
ErrorKind::InvalidData,
|
||||||
|
"bad immage dimensions",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for row in 0..4 {
|
||||||
|
for column in 0..128 {
|
||||||
|
let mut byte = 0u8;
|
||||||
|
for bit in 0..8 {
|
||||||
|
byte = byte >> 1;
|
||||||
|
let x = column;
|
||||||
|
let y = row * 8 + bit;
|
||||||
|
let pixel = img.get_pixel(x, y);
|
||||||
|
let luma = pixel.to_luma()[0];
|
||||||
|
if luma > 128 {
|
||||||
|
byte = byte | 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("{:02X}", byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: ft=rust
|
||||||
198
oled.mac
Normal file
198
oled.mac
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
.Z80
|
||||||
|
ASEG ; absolute addressing
|
||||||
|
ORG 100h ; skip CP/M
|
||||||
|
|
||||||
|
CR EQU 0Dh ; carriage return
|
||||||
|
LF EQU 0Ah ; new line
|
||||||
|
BDOS EQU 0005h ; BDOS entry point
|
||||||
|
PSTR EQU 09h ; print string
|
||||||
|
CRED EQU 01h ; read console
|
||||||
|
|
||||||
|
OLED EQU 50h ; base addr of OLED card
|
||||||
|
ORST EQU 04h ; reset command (H)
|
||||||
|
OBUF EQU 02h ; chip select (L), buffer (H)
|
||||||
|
ODB EQU 01h ; display byte (H)
|
||||||
|
OCMD EQU 00h ; command (L)
|
||||||
|
|
||||||
|
; 4 rows of display
|
||||||
|
OROWA EQU 0B0h ; select top row
|
||||||
|
OROWB EQU 0B1h ; select second row
|
||||||
|
OROWC EQU 0B2h ; select third row
|
||||||
|
OROWD EQU 0B3h ; select bottom row
|
||||||
|
|
||||||
|
OCOL0 EQU 04h ; left most column
|
||||||
|
OSELC EQU 10h ; select column command
|
||||||
|
OCOLL EQU 80h ; column count: 128 columns
|
||||||
|
|
||||||
|
; 128 columns from 4 to 131
|
||||||
|
; 1Xh, 0Yh - XY = 04h to 83h
|
||||||
|
|
||||||
|
; MAIN
|
||||||
|
CALL OINIT ; init OLED
|
||||||
|
CALL OCLS ; clear screen
|
||||||
|
CALL PROMPT ; print prompt
|
||||||
|
|
||||||
|
CALL OCSTART ; go to start
|
||||||
|
CALL READLINE ; read row A
|
||||||
|
CALL READLINE ; read row B
|
||||||
|
CALL READLINE ; read row C
|
||||||
|
CALL READLINE ; read row D
|
||||||
|
|
||||||
|
RET ; exit to CP/M
|
||||||
|
|
||||||
|
|
||||||
|
READLINE:
|
||||||
|
LD D,OCOLL ; number of columns
|
||||||
|
READLINE1:
|
||||||
|
PUSH DE
|
||||||
|
CALL READHEX ; read hex input from console
|
||||||
|
CALL ODATA ; write to OLED
|
||||||
|
POP DE
|
||||||
|
DEC D ; count donw columns
|
||||||
|
JP NZ,READLINE1 ; next column
|
||||||
|
RET
|
||||||
|
|
||||||
|
OINIT:
|
||||||
|
CALL ORESET ; reset OLED
|
||||||
|
LD HL,OINITSEQ ; commands to send
|
||||||
|
OINITLOOP:
|
||||||
|
LD A,(HL) ; load command byte to A
|
||||||
|
CP 0FFh ; check if we are done
|
||||||
|
RET Z ; marker reached
|
||||||
|
CALL OCOMMAND ; send command from A
|
||||||
|
INC HL ; next command
|
||||||
|
JR OINITLOOP ; send next command
|
||||||
|
|
||||||
|
ORESET:
|
||||||
|
LD C,OLED ; base I/O address
|
||||||
|
LD B,ORST OR OBUF ; RST H, /CS H, DB L
|
||||||
|
OUT (C),A ; write any A, to (C) + B
|
||||||
|
REPT 4
|
||||||
|
NOP ; delay
|
||||||
|
ENDM
|
||||||
|
LD B,OBUF ; clear RST
|
||||||
|
OUT (C),A ; send
|
||||||
|
REPT 20
|
||||||
|
NOP ; long delay
|
||||||
|
ENDM
|
||||||
|
RET
|
||||||
|
|
||||||
|
OCLS:
|
||||||
|
CALL OCSTART ; set start
|
||||||
|
CALL OCLSROW ; clear row A
|
||||||
|
CALL OCLSROW ; clear row B
|
||||||
|
CALL OCLSROW ; clear row C
|
||||||
|
CALL OCLSROW ; clear row D
|
||||||
|
RET
|
||||||
|
|
||||||
|
; set cursor to start
|
||||||
|
OCSTART:
|
||||||
|
LD A,OSELC ; select column
|
||||||
|
CALL OCOMMAND
|
||||||
|
LD A,OCOL0 ; column 0
|
||||||
|
CALL OCOMMAND
|
||||||
|
LD A,OROWA ; select first row
|
||||||
|
CALL OCOMMAND
|
||||||
|
RET
|
||||||
|
|
||||||
|
OCLSROW:
|
||||||
|
;XOR A ; display byte to write (0)
|
||||||
|
LD A,0FFh ; turn on all pixels
|
||||||
|
LD D,OCOLL ; count columns in D
|
||||||
|
OCLSROW1:
|
||||||
|
CALL ODATA ; write A to displey
|
||||||
|
DEC D ; next column
|
||||||
|
JR NZ,OCLSROW1
|
||||||
|
RET
|
||||||
|
|
||||||
|
; A = command to send to OLED
|
||||||
|
OCOMMAND:
|
||||||
|
LD C,OLED ; base I/O
|
||||||
|
LD B,OCMD ; send command
|
||||||
|
OUT (C),A ; send
|
||||||
|
REPT 4
|
||||||
|
NOP
|
||||||
|
ENDM
|
||||||
|
LD B,OCMD OR OBUF
|
||||||
|
OUT (C),A ; send
|
||||||
|
REPT 10
|
||||||
|
NOP
|
||||||
|
ENDM
|
||||||
|
RET
|
||||||
|
|
||||||
|
; Write to OLED memory
|
||||||
|
; A = graphic byte to dispaly memory
|
||||||
|
ODATA:
|
||||||
|
LD C,OLED ; base I/O
|
||||||
|
LD B,ODB ; select Data Byte mode
|
||||||
|
OUT (C),A ; output byte
|
||||||
|
REPT 4
|
||||||
|
NOP
|
||||||
|
ENDM
|
||||||
|
LD B,OBUF OR ODB
|
||||||
|
OUT (C),A ; output byte
|
||||||
|
NOP
|
||||||
|
NOP
|
||||||
|
RET
|
||||||
|
|
||||||
|
; Read byte from console
|
||||||
|
READ:
|
||||||
|
LD C,CRED ; read from console
|
||||||
|
CALL BDOS ; call CP/M
|
||||||
|
RET ; A=CHAR
|
||||||
|
|
||||||
|
; Reads 4 bit value (0-F)
|
||||||
|
READNIB:
|
||||||
|
CALL READ
|
||||||
|
LD B,41h ; compare with 'A' (10)
|
||||||
|
CP B
|
||||||
|
JP NC,RNB1 ; A>=B
|
||||||
|
SUB 30h ; sub '0'
|
||||||
|
RET
|
||||||
|
RNB1:
|
||||||
|
SUB 41h-10 ; sub 'A'-10
|
||||||
|
AND 0Fh ; clear to 4 bits so 'a-f' also work
|
||||||
|
RET
|
||||||
|
|
||||||
|
; Reads two bytes (0-F) from console
|
||||||
|
; A = byte read
|
||||||
|
READHEX:
|
||||||
|
CALL READNIB ; read MSD nibble
|
||||||
|
SLA A ; shift 4 bits
|
||||||
|
SLA A
|
||||||
|
SLA A
|
||||||
|
SLA A
|
||||||
|
LD B,A ; B=A
|
||||||
|
PUSH BC ; save B
|
||||||
|
CALL READNIB ; read LSD nibble
|
||||||
|
POP BC ; restore B
|
||||||
|
OR B ; OR B to A
|
||||||
|
RET
|
||||||
|
|
||||||
|
PROMPT:
|
||||||
|
LD C,PSTR ; load function number
|
||||||
|
LD DE,PROMPTMSG ; load string addr
|
||||||
|
CALL BDOS ; call CP/M
|
||||||
|
RET
|
||||||
|
|
||||||
|
PROMPTMSG:
|
||||||
|
DB 'OLED:>', CR, LF,'$' ; string terminated with $
|
||||||
|
|
||||||
|
; Initialization sequence
|
||||||
|
; 081h,080h - set contrast (080h full)
|
||||||
|
; 020h,000h - set horizontal window wrapping
|
||||||
|
; 021h,004h,083h - window full width
|
||||||
|
; 022h,000h,003h - window full height
|
||||||
|
OINITSEQ:
|
||||||
|
DB 0AEh,0D5h,0A0h,0A8h
|
||||||
|
DB 01Fh,0D3h,000h,0ADh
|
||||||
|
DB 08Eh,0D8h,005h,0A1h
|
||||||
|
DB 0C8h,0DAh,012h,091h
|
||||||
|
DB 03Fh,03Fh,03Fh,03Fh
|
||||||
|
DB 081h,070h,0D9h,0D2h
|
||||||
|
DB 0DBh,034h,0A6h,0A4h
|
||||||
|
DB 0AFh,020h,000h,021h
|
||||||
|
DB 004h,083h,000h,003h
|
||||||
|
DB 0FFh ; end marker
|
||||||
|
|
||||||
|
END
|
||||||
BIN
oled_compute.png
Normal file
BIN
oled_compute.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
oled_cpm.png
Normal file
BIN
oled_cpm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 983 B |
BIN
oled_tog_hxd.png
Normal file
BIN
oled_tog_hxd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 616 B |
BIN
oled_tog_hxd_grad.png
Normal file
BIN
oled_tog_hxd_grad.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
oled_zilog.png
Normal file
BIN
oled_zilog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 858 B |
Reference in New Issue
Block a user