diff --git a/ppm viewer/AF.dev b/ppm viewer/AF.dev new file mode 100644 index 0000000..6e1b37c Binary files /dev/null and b/ppm viewer/AF.dev differ diff --git a/ppm viewer/README.md b/ppm viewer/README.md new file mode 100644 index 0000000..58bc772 --- /dev/null +++ b/ppm viewer/README.md @@ -0,0 +1,16 @@ +# PPM image viewer + +Reads a ppm image from an input device (AF.dev by default) +and displays it on SicTools builtin graphical screen. + +To resize and convert your image you can use ffmpeg: +```{sh} +ffmpeg -i image.png -vf scale="64x-1" AF.ppm && mv AF.ppm AF.dev +``` + +- Source code: ppm.asm +- Graphical screen: 64x64 at A000 + - dimensions can be adjusted by changing their values in code +- Frequency: any +- Author: Jakob Jesenko, 2026 + diff --git a/ppm viewer/ppm.asm b/ppm viewer/ppm.asm new file mode 100644 index 0000000..ecefff7 --- /dev/null +++ b/ppm viewer/ppm.asm @@ -0,0 +1,195 @@ +. +. ppm.asm - prgram for dispaying of ppm images +. +. notice: any overflow of graphical screen is also +. copied to memory however only top left (64x64 pixels) +. remain visible +. +. default values from Sictools: +. - Graphical screen address: 0x00A000 +. - Columns: 64 +. - Rows: 64 +. default input device inputd: 0xAF +. + + +ppm START 0 + LDA #stack . setup stack + STA sp + CLEAR B +hloop CLEAR A . write image metadata to stdout + RD inputd + WD #1 + COMP #10 + JEQ ln2 + J hloop +ln2 CLEAR A + RD inputd + COMP #35 .# + JEQ comm + J dims1 +comm WD #1 +ln2lp CLEAR A + RD inputd + WD #1 + COMP #10 + JEQ dims + J ln2lp +dims RD inputd +dims1 COMP #32 + JEQ dims1e + WD #1 + SUB #48 .0 + ADDR A,B + LDA #10 + MULR A,B + RD inputd + J dims1 +dims1e WD #1 + LDA #10 + DIVR A,B + STB width + CLEAR B + RD inputd +dims2 COMP #10 + JEQ dims2e + WD #1 + SUB #48 .0 + ADDR A,B + LDA #10 + MULR A,B + RD inputd + J dims2 +dims2e WD #1 + LDA #10 + DIVR A,B + STB height + CLEAR B + RD inputd +dims3 COMP #10 + JEQ dims3e + WD #1 + SUB #48 .0 + ADDR A,B + LDA #10 + MULR A,B + RD inputd + J dims3 +dims3e WD #1 + LDA #10 + DIVR A,B + STB maxval + CLEAR B + + LDA width + MUL height + STA pixcnt + +mainlp CLEAR A + CLEAR B + RD inputd . read color data for one pixel + STCH red + RD inputd + STCH green + RD inputd + STCH blue + JSUB intens . calculate color intensity + LDCH clrmax + DIV #64 . construct pixel color according to + ADDR A,B . graphical screen specification + SHIFTL B,2 + LDCH red + DIV #64 + ADDR A,B + SHIFTL B,2 + LDCH green + DIV #64 + ADDR A,B + SHIFTL B,2 + LDCH blue + DIV #64 + ADDR B,A + + STCH @pixptr . print pixel to graphical screen + LDA pixptr . calculate next pixel position + ADD #1 + STA pixptr + LDA pixctr + ADD #1 + STA pixctr + DIV width + MUL width + COMP pixctr + JEQ ptradj . reset position to first column +adjret + + + LDA pixctr . check if all pixels have been + COMP pixcnt . displayed + JEQ halt + J mainlp + J halt + +ptradj LDA pixptr + SUB width + ADD cols + STA pixptr + J adjret + + +halt J halt + +. calculate color intensity by extracting +. color component, that has the highest +. value +. this might not be the correct algorhitm, +. but produces adequate results +intens STA @sp . push registers + LDA sp + ADD #3 + STA sp + STB @sp + ADD #3 + STA sp + ... + CLEAR A + LDA red + COMP green + JLT swpgrn +retgrn COMP blue + JLT swpblu +retblu STA clrmax + ... + LDA sp . pop registers + SUB #3 + STA sp + LDB @sp + SUB #3 + STA sp + LDA @sp + RSUB +swpgrn LDA green + J retgrn +swpblu LDA blue + J retblu + + +inputd BYTE X'AF' +width RESW 1 +height RESW 1 +maxval RESW 1 +pixcnt RESW 1 +rows WORD 64 +cols WORD 64 +pixptr WORD X'00A000' +screen WORD X'00A000' +pixctr WORD 0 +srtptr RESW 1 +red RESW 1 +green RESW 1 +blue RESW 1 +clrmax RESW 1 +sp RESW 1 +stack RESW 1024 + + END ppm