This works, it sets the graphical mode and clears the screen.
Second Code Skipping the int 25h version
## Track read part
xor ax, ax ; DS = 0
mov ds, ax
cld
mov ah, 2h ; int13h function 2 track read
mov al, 2 ; number of tracks ( should be 2 for reading only palette)
mov ch, 0 ; from cylinder number 0
mov cl, 2 ; the sector number 2 - second sector (starts from 1, not 0)
mov dh, 0 ; head number 0
xor bx, bx ; BX = 0
mov es, bx ; ES = 0
mov bx, 7e00h ; Offset from above
int 13h
call setpal
## End part with setpalette routine
## appending palette.colors
## and a raw image
setpal:
mov dx,3c8h
xor al,al
mov di, ax
out dx,al
inc dx
mov cx,256*3
mov si,07e00h
rep outsb
ret
times 510 - ($-$$) db 0
dw 0xaa55
include 'palette.colors'
times 2048 - ($-$$) db 0
file 'image.raw'
Seems there is still a header on the RAW file, lets look at how I made this.
NOTE! .. Below converts an image with a STANDARD VGA palette, not a custom one as used above
Gimp menu Image > Mode > Indexed and select your just imported palette. (Do not remove unused colors)
Flip vertical (bmp writes image upside/down)
Export as BMP Compatibility Options > Do not write color space information
Looking with ghex at the file I saw that there was a header 0x415 bytes large. (Probably still palette colors in there)
dd if=shoes.bmp of=cutshoe.bmp bs=1 skip=1078 (0x415h + 3?) worked for me
Loading the extra tracks didn’t work for me?!?! But how could I define tracks/sectors and heads on a virtual floppy?
I tried to write sectors using debug.com
start dosbox
imgmount a: /tmp/floppy.img -t floppy
debug.com bootsector.bin
-r bx 01
-r cx 512
; set bx:cx for size
-w 100 0 0 1
; write from address 100, drive 0 (a), sector 0, number of sectors
; testing
-l 100 0 0 1
;load sector to addr 100 drive 0 sector 0 number of sectors
This used to work with real disks on a real machine, not in dosbox ?!?!
my way to create a disk in linux
dd if=bootblock.bin of=disk1.img bs=512 count=1 seek=0
dd if=palette.col of=disk1.img bs=512 count=1 seek=1 # or 2?
dd if=shoes.raw of=disk1.img bs=512 count=10000 seek=17
It looks like I can’t read futher than 18 sectors on a virtual floppy. What next? Head=1? Cylinder=1? Below the info from a floppy image before altering.
DOS/MBR boot sector, code offset 0x3c+2, OEM-ID “MSDOS5.0”, root entries 224, sectors 2880 (volumes <=32 MB), sectors/FAT 9, sectors/track 18, serial number 0x1c2a0d0f, unlabeled, FAT (12 bit), followed by FAT
Appending the RAW to a executable gave me problems to. (Without making a bootdisk)
Above and below weird data. Appending the data to the executable needs some work also.
At least for today let me display this image correctly 🙂
use16
org 0x100
; set mode 320x200 256 colors palette
mov ah,0x0
mov al,13h
int 10h
; clear screen routine, not really needed
clearscreen:
push ax
mov ax, 0a000h
mov es, ax
pop ax
xor di, di
inc ax
mov cx, 64000 ; 320x200
rep stosb
; call file loader
call Loadfile
; after displaying the image or displaying an error, wait for keypress to exit
waitforkeyloop:
MOV AH,1
INT 16h
JZ waitforkeyloop
XOR AH,AH
INT 16h
Exit:
MOV AX,3 ; default text mode 3
INT 10h
MOV AX,4C00h ; exit to dos (terminate process)
INT 21h
Loadfile:
MOV DX,filename
MOV AX,3D00h ; open filehandle
INT 21h
JC Err1
MOV BX,AX ; filehandle
MOV CX,0FFFFh ; size
mov dx,0a000h ; destination 0000:a000h - Screen memory
mov ds,dx
MOV DX,0
MOV AH,3Fh ; read from file
INT 21h
JC Err1
MOV AH,3Eh ; close filehandle
INT 21h
RET
; print error
Err1:
push cs ; make ds same as cs
pop ds
MOV DX,TxtErr1 ; error
MOV AH,09h
INT 21h
RET
filename DB "shoes.bmp",0
TxtErr1 DB "shoes.bmp not found!",7,10,13,"$"
I’ve got a Wifi outside of my network for guest and emergency. ( 2 SSIDs)
Then a main Wifi router in my livingroom, one in my workshop/studio and one in the Attic (Electronics Lab)
So three main Wifi AccessPoints. These all have the same SSID’s but on different frequencies. That way i’ve got roaming in and outside my house. Also some virtual accesspoints are configured. I’ve got a main, folkband, IOT, guest-inside all on 2.4Ghz and 5Ghz.
I watched a lot of YT presentations about Mikrotik Wifi.
So I ended up with DFS safe channels 20Mhz for 2.4 and 20/40Mhz Ce for 5Ghz. (subchannels for each after some frequency scanning) (2.4 does a failback to 20Mhz whenever there is even one client detected which connects only on this band. Such as some old IOT stuff) 2.4 in only 1,6 and 11 no overlap, each on another device. 300Mbps is sufficient for my wifi 🙂
I’ve got accesslists in place and i’m going to read into kicking a client when the signal strenght is below -50dB
80386 (DX) Computer
Besides my 8088 and 8086 machines I needed a machine which could run our old demo’s. So I bought a new toy.
It has 8Mb Ram and runs at 40Mhz.
I’ve noticed that many of my VGA register manipulation code, can’t be run on a modern VGA monitor, I need to use a CRT for that .. Another thing to buy
Needed to fix arduino code, due to the TFT_eSPI library issues. And I’ve got a S3 with another resolution, but that was an easy fix. Then needed to reinstall nodejs with another version. Had to modify the code because the tcp server would not start. Weird errors logging, but in the end fixed … very cool
I probably end up designing a 3D printed case that looks like a monitor or tv.
While still having a love-hate relationship with Visual Studio (I’m a Vim guy), here is my C64 coding setup. (for now)
Needed: Vice (C64 emulator (and more)) C64 Debugger (embeds above in an awesome debugger) Visual Studio Kickass C64 assembler (you need java for this) (http://theweb.dk/KickAssembler/Main.html)
Visual Studio click extensions and add kickass by Captain Jinx
https://sourceforge.net/projects/c64-debugger/ This is Commodore 64, Atari XL/XE and NES code and memory debugger that works in real time. It is quick prototyping tool where you can play with Commodore 64 machine and its internals.
Awesome debugger, many many options. Read the README
I’ve got mostly installed in /data Change accordingly
Create new file, press ctrl-shift-p and invoke kickass debug!
I didn’t find an easy and working movie player for wide screen setups. Like double/triple monitor setups.
I’ve got 3x 1920×1080 monitors connected to my battlestation. With a resolution of 5760×1080
Simple Python code to play a movie fullscreen
# importing vlc module
import vlc
# creating vlc media player object
media_player = vlc.MediaPlayer()
# media object
media = vlc.Media("movie.mp4")
# setting media to the media player
media_player.set_media(media)
media_player.toggle_fullscreen()
# start playing video
media_player.play()
But trying to get this stable working, I resorted to pysimplegui
#!/usr/bin/env python3
import PySimpleGUI as sg
import vlc
import sys
from sys import platform as PLATFORM
try:
movie=sys.argv[1]
except:
print(sys.argv[0] + " filename")
exit()
sg.theme('DarkBlue')
layout = [[sg.Image('', size=(5760, 1080), key='-VID_OUT-')]]
window = sg.Window('Triple movie player', layout, no_titlebar=True, margins=(0,0),location=(0,0), size=(5760,1080), keep_on_top=True, finalize=True,resizable=False)
window.bring_to_front()
window.Maximize()
window.bind("<Escape>", "-ESCAPE-")
window.bind("<Return>", "-ENTER-")
window['-VID_OUT-'].expand(True, True)
inst = vlc.Instance()
list_player = inst.media_list_player_new()
media_list = inst.media_list_new([])
list_player.set_media_list(media_list)
player = list_player.get_media_player()
if PLATFORM.startswith('linux'):
player.set_xwindow(window['-VID_OUT-'].Widget.winfo_id())
else:
player.set_hwnd(window['-VID_OUT-'].Widget.winfo_id())
media_list.add_media(movie)
list_player.set_media_list(media_list)
list_player.play()
while True:
event, values = window.read(timeout=1000)
if event == sg.WIN_CLOSED:
break
if event == '-ENTER-':
list_player.play()
if event == '-ESCAPE-':
list_player.stop()
window.close()
window.close()
I’ve converted some of my Vuze media to the correct resolution using kdenlive.
I’ve added a new profile. 5760×1080 dont forget to change the display ratio!
Note: I love everything streamable from my own servers. So if its music or movies i tried the lot. (Another post about movie streaming using Jellyfin,Phpmytube and more)
I’ve got music in mp3, flac and ogg and I have been using below players for a long time
If you have any other suggestion mentioned below, let me know!
MPD – A linux terminal mp3 player (using ncmpc) XMMS/XMMS2 – Linux gui music player ( The winamp for linux)
Then i moved to
VLC – Sporadic music file playing Clementine – Linux gui player
For a while Audacious, Rhythmbox and Amarok
And later spotify (Btw you CAN use spotify with local files)
Clementine was not updated very much, so I went with Strawberry Music Player (which is a maintained clone of Clementine)
Tagging mp3s I did using Kid3, Picard and Mp3tag (with wine) Now with Strawberry
For a while I used some webbased mp3 players. I like it when I can stream my music from another location. But none were to my liking. It really has to have a Android client, and a secure connection.
Ampache
Funkwhale
Emby
Subsonic ( android client is $$ and broken)
Volumio
Koel
Jellyfin
In the old days i used even a simple php streamers
Linux OSses I currently use : Ubuntu, Centos/Rocky/Fedora, Raspbian (and msdos lol) Have used: Slackware,Gentoo, Kali, ELive, Suse,Debian,Mint,Puppy,Lubuntu
Window managers I currently use
Xmonad – Tiling window manager
Gnome
Xmonad with clusterssh on 14 servers. (Using my serverpath identify trick)
Created this for usage with Kodi, for our own personal movies, which can’t be scraped by movie scrapers obviously. (dvd-rip,digital video, mobile movies, OBS, Vuze and Nikon movies for example)
Needed libraries: (install with pip) pathlib, Pillow, pymediainfo,PySimpleGUI,python-vlc
NFO created
Title – editable (generated from filename) Duration – mediainfo data in seconds Plot – Single line type it yourself Actors – Predefined Tags – Predefined checkboxes Country – Pulldown ( I use this as location, Scotland, Asia, Garden) Year – default 2023, copy button from mobile phone metadata year Genre – Pulldown
Works
File select and loaded
Play movie, scrub thretro movie
Create snapshot
Play/Mute/Pause
Playtimer
Auto update NFO text field with selectable options
Poster art – rotate
Poster art – brightness
Reload Thumb after snapshotting
Year extracted from filename
add tag field
Next file (button AND functionality)
checkboxes from text list
Read NFO from file into fields
Poster art – aspect ratio
Needs work
Wish list
Poster art – contrast?
Low – more mediainfo?
Low – Media rotate??
Some ‘action’ screenshots
The GUI in action (V1)
Kodi example
CODE ( WIP ) V2 I place this python script in every library directory. So i can change the checkboxes and the NFO being generated. I fill the directory with symlinks for every movie I want to have included in this directory, but this is not needed. (thats the way I like to do things) (This is the directory I scrape into Kodi)
from pathlib import Path
from sys import platform as PLATFORM
import os
import re
import PySimpleGUI as sg
import vlc
from pymediainfo import MediaInfo
from PIL import Image, ImageEnhance, ImageTk, ImageOps, ImageFilter
from xml.etree import ElementTree as ET
'''
WARNING, NFO overwrites previous!!
'''
alltags = ["music", "pipes", "computer","bbq","fun","art","travel","hobby","family","retro","compilation","retro","vuze"]
#------- WINDOWS FIX --------#
if PLATFORM.startswith('linux'):
print("yeah linux baby!")
else:
os.add_dll_directory(r'E:\VLC')
duration=0
tmptag=""
def nextFile(currentfile,dir):
newfile=""
dirpath = os.path.dirname(dir)
fileList = []
for f in os.listdir(dirpath):
#fpath = os.path.join(dirpath, f)
fpath = f
if os.path.isfile(fpath) and f.endswith(('.mp4', '.mov', '.mpg','.avi','.mkv','.3gp')):
fileList.append(fpath)
fileList.sort()
for i in range(len(fileList)):
# print("fileList[i] " + fileList[i])
try:
if (fileList[i]) == currentfile:
newfile=fileList[i+1]
break
except:
newfile=fileList
return newfile
def loadthumb(thumbfile):
# IF exists
path_to_file = thumbfile
path = Path(path_to_file)
if path.is_file():
im = Image.open(thumbfile)
im=ImageOps.contain(im, (640,640))
thumbimage = ImageTk.PhotoImage(image=im)
window['thumb'].update(data=thumbimage)
else:
window['thumb'].update("")
def loadnfo(file):
#LOAD NFO
nfo=file + ".nfo"
path = Path(nfo)
if path.is_file():
f = open(nfo, "r")
innfo=f.read()
f.close()
# print ("file : " + nfo)
innfo="".join([s for s in innfo.strip().splitlines(True) if s.strip()])
# Clear some fields
window['year'].update("")
window['plot'].update("")
# Update fields test
if ET.fromstring(innfo).find('country') is not None:
nfolocation = ET.fromstring(innfo).find('country')
window['location'].update(value=nfolocation.text)
if ET.fromstring(innfo).find('year') is not None:
nfoyear = ET.fromstring(innfo).find('year')
window['year'].update(nfoyear.text)
if ET.fromstring(innfo).find('plot') is not None:
nfoplot = ET.fromstring(innfo).find('plot')
window['plot'].update(nfoplot.text)
if ET.fromstring(innfo).find('title') is not None:
nfotitle = ET.fromstring(innfo).find('title')
window['-NM-'].update(nfotitle.text)
if ET.fromstring(innfo).find('genre') is not None:
nfogenre = ET.fromstring(innfo).find('genre')
window['genre'].update(value=nfogenre.text)
window['coline'].update(False)
window['henri'].update(False)
window['monique'].update(False)
for actor in ET.fromstring(innfo).findall('actor'):
name = actor.find('role').text
if name == "Coline":
window['coline'].update(True)
if name == "Henri":
window['henri'].update(True)
if name == "Monique":
window['monique'].update(True)
for alltag in alltags:
window[alltag].update(False)
if ET.fromstring(innfo).find('tag') is not None:
for tag in ET.fromstring(innfo).findall('tag'):
if tag.text in window.AllKeysDict:
window[tag.text].update(True)
window['coline'].update(False)
window['henri'].update(False)
window['monique'].update(False)
for actor in ET.fromstring(innfo).findall('actor'):
name = actor.find('role').text
if name == "Coline":
window['coline'].update(True)
if name == "Henri":
window['henri'].update(True)
if name == "Monique":
window['monique'].update(True)
for alltag in alltags:
window[alltag].update(False)
if ET.fromstring(innfo).find('tag') is not None:
for tag in ET.fromstring(innfo).find('tag'):
window[tag.text].update(True)
else:
innfo=""
window['LOADNFO'].update(innfo)
#------- Button definition --------#
def btn(name):
return sg.Button(name, size=(6, 2), pad=(1, 1))
#def tag(name):
# return sg.Checkbox(name, enable_events=True)
#------- GUI definition & setup --------#
sg.theme('SystemDefaultForReal')
l1=sg.Text("New title")
l2=sg.Multiline(" ", expand_x=True, key='-OUT-', expand_y=True,justification='left', size=(20,15))
l3=sg.Multiline(" ", expand_x=True, key='LOADNFO', expand_y=True,justification='left', size=(20,15))
l4=sg.Text("Plot")
t1=sg.Input("", key='-NM-')
t2=sg.Input("", key='plot',enable_events=True)
cb=[]
for alltag in alltags:
cb.append(sg.Checkbox(alltag, key=alltag, enable_events=True))
cb.append(sg.Input("", key='addtag',size=(5, 1), enable_events=True))
cb.append(sg.Combo(["Lab","Datacenter","home","Outside","Outside","Lloydwebber","Steenweg","Enschede","Netherlands","Germany","Italy","Scotland","Canada","Egypt","Belgium","Sweden","Ireland","Asia","NewZealand","Hilversum"],default_value='Lab',key='location'))
cb.append(sg.Combo(["Storage","Funny","Vacation","Music","Relation"],default_value='Storage',key='genre'))
nameyear=[]
nameyear.append(sg.Checkbox("Coline", key='coline', enable_events=True,default=True))
nameyear.append(sg.Checkbox("Henri", key='henri', enable_events=True,default=True))
nameyear.append(sg.Checkbox("Monique", key='monique', enable_events=True,default=False))
nameyear.append(sg.Input("2023",key='year',size=(5, 1), enable_events=True))
nameyear.append(sg.Button("copyyear\nmetadata", key='copymeta', size=(20, 1), pad=(1, 1), enable_events=True))
nameyear.append(sg.Input("",key='metayear',size=(5, 1), enable_events=True))
nameyear.append(sg.Button("copyyear\nfilename", key='copyname', size=(20, 1), pad=(1, 1), enable_events=True))
nameyear.append(sg.Input("",key='fileyear',size=(5, 1), enable_events=True))
b1=sg.Button("WRITE NFO", key='write', enable_events=True)
b2=sg.Button("Exit", key='exit', enable_events=True)
#------- Layout total --------#
layout = [[sg.Input(key='-VIDEO_LOCATION-', visible=False, enable_events=True),
sg.FileBrowse(file_types=(("Video files", "*.mkv *.mov *.mp4 *3gp *avi *mpg"),)),btn('next')],
[sg.Text('Load media to start', key='-MESSAGE_AREA-')],
[sg.Image('', size=(600, 480), key='-VID_OUT-', pad=(1, 1)),sg.Image('', size=(600, 480), key='thumb', pad=(1, 1))],
[btn('mute'), btn('play'), btn('pause'), btn('stop'), btn('snap'), btn('snaprot'), btn('lighten'), btn('darken'), sg.Combo(["4:3","16:9","9:16"],key='aspect',enable_events=True)],
[sg.Slider(range=(0, 1000), default_value=1, expand_x=True, enable_events=True, orientation='horizontal', key='-SL-')],
[sg.Text('org title', key='orgtitle')],
[l1, t1, l4, t2],[cb],[nameyear],[b1, l2, l3, b2],
[sg.Text('GENERATED -= mini nfo writer =- PREVIOUS', key='footer')]
]
#------- Set window --------#
window = sg.Window('Mini NFO generator', layout, element_justification='center', finalize=True, resizable=True)
#------- VID out window --------#
window['-VID_OUT-'].expand(True, True)
#------------ Media Player Setup ---------#
inst = vlc.Instance()
list_player = inst.media_list_player_new()
media_list = inst.media_list_new([])
list_player.set_media_list(media_list)
player = list_player.get_media_player()
if PLATFORM.startswith('linux'):
player.set_xwindow(window['-VID_OUT-'].Widget.winfo_id())
else:
player.set_hwnd(window['-VID_OUT-'].Widget.winfo_id())
#------------ I Want default mute ---------#
player.audio_set_mute(True)
#------------ The Event Loop ------------#
while True:
event, values = window.read(timeout=1000) # run with a timeout so that current location can be updated
if event == sg.WIN_CLOSED:
break
if event == 'mute':
mutevalue = player.audio_get_mute()
if mutevalue==0:
player.audio_set_mute(True)
if mutevalue==1:
player.audio_set_mute(False)
if event == 'play':
list_player.play()
if event == 'pause':
list_player.pause()
if event == 'stop':
list_player.stop()
if event == 'snap':
list_player.pause()
filename = values['-VIDEO_LOCATION-']
shortfilename = filename.rsplit( ".", 1 )[ 0 ]
newname = shortfilename + "-poster.png"
player.video_take_snapshot(0, newname, 0, 0)
loadthumb(newname)
if event == 'snaprot':
list_player.pause()
filename = values['-VIDEO_LOCATION-']
shortfilename = filename.rsplit( ".", 1 )[ 0 ]
newname = shortfilename + "-poster.png"
im1 = Image.open(newname)
im1 = im1.rotate(90, Image.NEAREST, expand = 1)
im1 = im1.save(newname)
loadthumb(newname)
if event == 'lighten':
list_player.pause()
filename = values['-VIDEO_LOCATION-']
shortfilename = filename.rsplit( ".", 1 )[ 0 ]
newname = shortfilename + "-poster.png"
im1 = Image.open(newname)
im1 = ImageEnhance.Brightness(im1)
im1 = im1.enhance(1.2)
im1 = im1.save(newname)
loadthumb(newname)
if event == 'darken':
list_player.pause()
filename = values['-VIDEO_LOCATION-']
shortfilename = filename.rsplit( ".", 1 )[ 0 ]
newname = shortfilename + "-poster.png"
im1 = Image.open(newname)
im1 = ImageEnhance.Brightness(im1)
im1 = im1.enhance(0.8)
im1 = im1.save(newname)
loadthumb(newname)
if event == 'aspect':
filename = values['-VIDEO_LOCATION-']
shortfilename = filename.rsplit( ".", 1 )[ 0 ]
newname = shortfilename + "-poster.png"
if values['aspect'] == "4:3":
im1 = Image.open(newname)
im1 = im1.resize((1920 ,int(1920/4*3)), Image.ANTIALIAS)
im1 = im1.save(newname)
loadthumb(newname)
if values['aspect'] == "16:9":
im1 = Image.open(newname)
im1 = im1.resize((1920 ,int(1920/16*9)), Image.ANTIALIAS)
im1 = im1.save(newname)
loadthumb(newname)
if values['aspect'] == "9:16":
im1 = Image.open(newname)
im1 = im1.resize((int(1920/16*9),1080), Image.ANTIALIAS)
im1 = im1.save(newname)
loadthumb(newname)
if event == 'write':
filename = values['-VIDEO_LOCATION-']
shortfilename = filename.rsplit( ".", 1 )[ 0 ]
newname = shortfilename + ".nfo"
f = open(newname, "w")
f.write(out)
f.close()
loadnfo(shortfilename)
if event == 'copymeta':
if datefromfile is not None:
window['year'].update(datefromfile)
if event == 'copyname':
if fileyear is not None:
window['year'].update(fileyear)
if event == '-SL-':
pos=int(values['-SL-'])
player.set_position(pos/ 1000.0)
if values['coline'] == False:
colinetext = ""
if values['coline'] == True:
colinetext = """<actor>
<name>Coline Lastname</name>
<role>Coline</role>
</actor>"""
if values['henri'] == False:
henritext = ""
if values['henri'] == True:
henritext = """<actor>
<name>Henri Aanstoot</name>
<role>Henri</role>
</actor>"""
if values['monique'] == False:
moniquetext = ""
if values['monique'] == True:
moniquetext = """<actor>
<name>Monique Lastname</name>
<role>Monique</role>
</actor>"""
if event == '-VIDEO_LOCATION-':
if values['-VIDEO_LOCATION-'] and not 'Video URL' in values['-VIDEO_LOCATION-']:
media_list.remove_index(0)
media_list.add_media(values['-VIDEO_LOCATION-'])
list_player.set_media_list(media_list)
shortname = values['-VIDEO_LOCATION-']
shortname = shortname.rsplit( "/", 1 )[ 1 ]
nextfile=nextFile(shortname,"./")
shortname = shortname.rsplit( ".", 1 )[ 0 ]
window['-NM-'].update(shortname) # only add a legit submit
list_player.stop()
list_player.next()
thumbname=shortname + "-poster.png"
loadthumb(thumbname)
#Print org title
window['orgtitle'].update(values['-VIDEO_LOCATION-'])
loadnfo(shortname)
#DURATION
mi = MediaInfo.parse(values['-VIDEO_LOCATION-'])
duration=int(mi.tracks[0].duration/1000)
#DATE FROM media
metadate=mi.tracks[0].encoded_date
if metadate is not None:
datefromfile=next(iter(re.findall(r"[1][9][8-9][0-9]|[2][0][0-9]{2}", metadate)), None)
window['metayear'].update(datefromfile)
# YEAR FROM FILENAME
fileyear=next(iter(re.findall(r"[1][9][8-9][0-9]|[2][0][0-9]{2}", shortname)), None)
# year from filename
if fileyear is not None:
window['fileyear'].update(fileyear)
if event == 'next':
values['-VIDEO_LOCATION-'] = nextfile
window['-VIDEO_LOCATION-'].update(nextfile)
if values['-VIDEO_LOCATION-'] and not 'Video URL' in values['-VIDEO_LOCATION-']:
media_list.remove_index(0)
media_list.add_media(values['-VIDEO_LOCATION-'])
list_player.set_media_list(media_list)
shortname = values['-VIDEO_LOCATION-']
# shortname = shortname.rsplit( "/", 1 )[ 1 ]
nextfile=nextFile(shortname,"./")
#print(nextfile)
shortname = shortname.rsplit( ".", 1 )[ 0 ]
window['-NM-'].update(shortname) # only add a legit submit
list_player.stop()
list_player.next()
thumbname=shortname + "-poster.png"
loadthumb(thumbname)
#Print org title
window['orgtitle'].update(values['-VIDEO_LOCATION-'])
loadnfo(shortname)
#DURATION
mi = MediaInfo.parse(values['-VIDEO_LOCATION-'])
duration=int(mi.tracks[0].duration/1000)
#DATE FROM media
metadate=mi.tracks[0].encoded_date
if metadate is not None:
datefromfile=next(iter(re.findall(r"[1][9][8-9][0-9]|[2][0][0-9]{2}", metadate)), None)
window['metayear'].update(datefromfile)
# YEAR FROM FILENAME
fileyear=next(iter(re.findall(r"[1][9][8-9][0-9]|[2][0][0-9]{2}", shortname)), None)
# year from filename
if fileyear is not None:
window['fileyear'].update(fileyear)
# media_list.add_media(nextfile)
## shortname = nextfile.rsplit( ".", 1 )[ 0 ]
## window['-NM-'].update(shortname) # only add a legit submit
# print(nextfile)
# window['-VIDEO_LOCATION-'].update(nextfile)
# list_player.next()
# hier moeten wat update dingen bij!
# Add tag
if event == 'addtag':
tmptag="<tag>" + values['addtag'] + "</tag>"
#------------ exit ---------#
if event=='exit':
exit()
#------------ TAGS ---------#
subs=[x.Text for x in cb if x.get()==True]
for idx, x in enumerate(subs):
subs[idx]="<tag>" + subs[idx] + "</tag>"
if values['year'] == False:
year=str(2023)
else:
year=values['year']
if values['location'] == False:
location="Lab"
else:
location=values['location']
if values['plot'] == False:
plot=""
else:
plot=values['plot']
if values['genre'] == False:
genre="Storage"
else:
genre=values['genre']
#------------ NFO TEXT FIELD ---------#
out="""<movie>
<title>{}</title>
<plot>{}</plot>
<genre>{}</genre>
<duration>{}</duration>
<year>{}</year>
<country>{}</country>
{}
{}
{}
{}
{}
</movie>
""".format(values['-NM-'],plot,genre,duration,year,location,colinetext,henritext,moniquetext,tmptag, "\n".join(subs))
out="".join([s for s in out.strip().splitlines(True) if s.strip()])
window['-OUT-'].update(out)
#------------ Messages and timer ---------#
# update elapsed time if there is a video loaded and the player is playing
if player.is_playing():
window['-MESSAGE_AREA-'].update("{:02d}:{:02d} / {:02d}:{:02d}".format(*divmod(player.get_time()//1000, 60),
*divmod(player.get_length()//1000, 60)))
else:
window['-MESSAGE_AREA-'].update('Load media to start' if media_list.count() == 0 else 'Ready to play media' )
window.close()
~/.dosbox/dosbox-*.conf
;-------- bottom part
[autoexec]
# Lines in this section will be run at startup.
# You can put your MOUNT lines here.
mount c: /home/myusername/projects/dos
c:
The files
A.BAT – Runs editor, masm,linker (start with a<space>progname
DEBUG.COM – msdos debugger
EXE2BIN.EXE – exe to com (if segments allow)
GFX.ASM – example template (see below)
LINK.EXE – masm linker
MASM.EXE – masm compiler
Q* – editor stuff
Q.EXE – editor
SR.EXE – sourcer
SYMDEB.EXE
TASM.EXE – turbo assembler
TD.EXE – turbo debugger
TLINK.EXE – turbo linker
Template
; everything in 64k CS, DS, and SS are the same
.model small
; start pointer
.stack 100h
.code
start:
; set mode 13 (320x200 * 265 colors palette)
mov ah,0
mov al,13h
int 10h
; set pixel in the middle color 2 (cyan)
mov ah,0ch
mov al,2
mov cx,160
mov dx,100
int 10h
; wait key input
mov ah,0
int 16h
; set mode back to text
mov ah,0
mov al,3
int 10h
; exit to dos
mov ax,4c00h
int 21h
end start
Usage
start dosbox a gfx (edit gfx.asm example) esc, q, e gfx (run program)
Example uses a shelly sensor, which has a offset mode in its new firmware. So below is not needed any more. But the example can be used for any calibration/adjustments.
I’ve put two examples in the NodeRed function
First the solution
var temperature=msg.payload.tC;
var humidity=msg.payload.tF;
// calc new offset example
// simple offset + 2.3 off real measurement
msg.payload.tC=temperature + 2.3;
// more complex example
// take two measurements (with a big difference)
msg.payload.tF=1.11 * (humidity - 1);
return msg;
First adjustment is plus or minus a value. Second is more precise when the temperature needs more adjusting
Dots on the red line are measured values Blue is how it should be
So measured was 2.8 but should be 2 And measured 14.5 but needs to be 15
slope = (14.5-2.8)/(15-2) = 0.9
To get the multiplication factor = 1/0.9 = 1.1111
=(2.8-heightadjust)*1,1111 should give us 2
2/1.1111 = 2.8 – heightadjust
1.8 = 2.8 – heightadjust = 1
So the formula is realhumid = 1,1111 * ( measuredhumid – adjust )
Moving dhcp from isc-dhcp-server to Mikrotik. And playing with theDude and speedtesting.
I got an old linux gateway which only runs a dhcp server. Time to move this to a Mikrotik router.
The config on this isc-dhcp-server is huge! So i was planning to migrate some one by one by hand. Maybe writing a script to do this automatically later on.
I’ve got loads of static configured hosts, so I change these
Change static entry in dhcp to a deny booting entry
The dude is a cool tool which connects to your MT and generates all kinds of cool info. I was trying to get the frequency spectral scan working. But it generates a nice network map also.
Easy to install under linux
Install wine
Download thedude from the MT website
start “wine dude_install.exe”
cd ” /home/$USER/.wine/drive_c/Program Files (x86)/Dude”
wine dude.exe
While moving a lot from my gateway to Mikrotik, I still have to come up with a plan to migrate my netboot.xyz PXE server to TFTP/ipxe using a migrated dhcpd server. I probably end up using a separate dhcp instance which handles only the PXE requests.
"If something is worth doing, it's worth overdoing."