Arduino based LPT2MIDI device for my retro PC...
Arduino code:
void receive() {
Serial.write((PIND>>3)+(PINB<<5)&255);
}
void setup() {
DDRB = 0;
DDRD = 0;
Serial.begin(31250); // MIDI uses 31.25 kbps serial
attachInterrupt(digitalPinToInterrupt(2), receive, RISING);
}
If you want to increase the serial buffer size, then change the parameter SERIAL_TX_BUFFER_SIZE in HardwareSerial.h to your liking. This arrangement has the added benefit that if the MIDI messages are arriving too fast at certain point in time, but not others, then Arduino buffers them and one may avoid some issues that would otherwise be present (although LPT isn't particularly fast port so the benefit might not be that big).
You can trap port operations on 386 or higher using the following code in DOS. Requires EMM386 (loadhigh works). This version is rather simplistic and doesn't implement all the functions such as those of port 331h so it only works in some cases (like my custom Supaplex hack below) where basic writes to 330h are sufficient. However, it should be fairly easy to implement the missing functions or just add this device to existing project like SOFTMPU.
; nasm -fbin trapmidi.asm -o trapmidi.com
org 100h
mov ax, 4a15h ; EMM386 I/O trap
mov bx, 0
mov dx, 330h
shl edx, 16
mov dx, 330h
mov cx, 1
mov si, io_dispatch_table
mov di, end
int 2fh
mov ax, 0x3100
mov dx, 512/16
int 21h
align 16
handler330:
mov ah, al
mov al, 255
mov dx, 0x37a ; 1st parallel port status register
out dx, al
times 4 in al, dx
mov al, ah
mov dx, 0x378 ; 1st parallel port data register
out dx, al
times 4 in al, dx
xor al, al
mov dx, 0x37a ; status register is used to signal
out dx, al ; port operation on rising edge
times 8 in al, dx
retf
align 16
io_dispatch_table:
dw 0x0330
dw handler330
end:
While we're at it, let's hack away a few bugs in roland.snd of my favorite DOS era game, Supaplex.
; nasm -fbin roland.asm -o sp_org\roland.snd
incbin "roland.snd", $, 0x0085-$ ; remove port delays
retn
incbin "roland.snd", $, 0x0098-$ ; remove port delays
mov dx, 330h
mov al, ah
out dx, al
retn
incbin "roland.snd", $, 0x0189-$ ; remove volume op (causes clipping)
times 3 nop
incbin "roland.snd", $, 0x018e-$ ; remove volume op (causes clipping)
times 3 nop
incbin "roland.snd", $, 0x0193-$ ; remove volume op (causes clipping)
times 3 nop
incbin "roland.snd", $, 3968
Sound Blaster output is also not working right (on my particular setup) so let's rewrite blaster.snd.
; nasm -fbin blaster.asm -o sp_org\blaster.snd
%macro waitdsp 0
%%wait:
in al, dx
or al, al
js %%wait
%endmacro
push ax
push bx
push cx
push dx
cmp ax, 0
jne skip0
mov cx, explosion
mov di, infotron - explosion - 1
jmp short start
skip0:
cmp ax, 1
jne skip1
mov cx, infotron
mov di, push - infotron - 1
jmp short start
skip1:
cmp ax, 2
jne skip2
mov cx, push
mov di, zonk - push - 1
jmp short start
skip2:
cmp ax, 3
jne skip3
mov cx, zonk
mov di, bug - zonk - 1
jmp short start
skip3:
cmp ax, 4
jne skip4
mov cx, bug
mov di, base - bug - 1
jmp short start
skip4:
cmp ax, 5
jne skip5
mov cx, base
mov di, exit - base - 1
jmp short start
skip5:
cmp ax, 6
jne skip6
mov cx, exit
mov di, end - exit - 1
jmp short start
skip6:
jmp skip
start:
mov dx, 0x0a ; DMA: write mask register
mov al, 15; ; channel 1 disabled
out dx, al
mov dx, 0x0c ; DMA: clear byte pointer flip-flop
mov al, 0
out dx, al
mov dx, 0x0b
mov al, 0x49 ; single-cycle playback on channel 1
out dx, al
mov bx, cs
shl bx, 4
add bx, cx ; offset
mov dx, 0x02 ; DMA: channel 1 address
mov al, bl
out dx, al
mov al, bh
out dx, al
mov ax, cs
mov bx, cx
shr bx, 4
add bx, ax
shr bx, 12 ; DMA: page in bx
mov dx, 0x83 ; DMA: channel 1 page
mov al, bl
out dx, al
mov bx, di
mov dx, 0x03 ; DMA channel 1 count
mov al, bl
out dx, al
mov al, bh
out dx, al
mov dx, 0x0a
mov al, 1 ; DMA 1 channel enabled
out dx, al
mov dx, 0x22c ; sound blaster (A220) DSP write data
waitdsp
mov al, 0x40 ; sample rate
out dx, al ; SB
waitdsp
mov al, 256 - 1000000/8333
out dx, al ; SB
waitdsp
mov al, 0x14 ; 8-bit PCM output
out dx, al ; SB
waitdsp
mov al, bl ; lo(size)
out dx, al ; SB
waitdsp
mov al, bh ; hi(size)
out dx, al ; SB
skip:
pop dx
pop cx
pop bx
pop ax
iret
state:
db 0
explosion:
incbin "explode.raw"
infotron:
incbin "infotron.raw"
push:
incbin "push.raw"
zonk:
incbin "zonk.raw"
bug:
incbin "bug.raw"
base:
incbin "base.raw"
exit:
incbin "exit.raw"
end:
We also need to make changes to the main binary and while we're at it, let's convert it to a .COM just for kicks.
; nasm -fbin supaplex.asm -o sp_org\supaplex.com
org 100h
mov dx, 0x226 ; reset sound blaster
mov al, 1
out dx, al
sub al, al
delay:
dec al
jnz delay
out dx, al
sub cx, cx
empty:
mov dx, 0x22e
in al, dx
or al, al
jns nextattempt
sub dl, 4
in al, dx
cmp al, 0xaa
je resetok
nextattempt:
loop empty
resetok:
mov dx, 0x22c ; enable sound blaster dac
wait2:
in al, dx
and al, 0x80
jnz wait2
mov al, 0xd1
out dx, al
mov ax, cs
add ax, 0x58d4 ; initial ss
add ax, (512+0x0100)/16 ; skip org and loader
mov ss, ax
mov sp, 0x0080 ; initial sp
mov ax, cs
add ax, 0x0aff ; initial cs
add ax, (512+0x0100)/16 ; skip org and loader
push ax
mov ax, 0x0010 ; initial ip
push ax
retf ; jumps to start
times 512-($-$$) nop
incbin "supaplex\supaplex.exe", $, 0x0526-$ ; 50:70 timing
db 0xa0, 0x92, 0x0d ; mov al, [0xd92]
inc al
and al, 7
db 0xa2, 0x92, 0x0d ; mov [0xd92], al
cmp al, 3
db 0x74, 0x6d ; je 0x5a1
cmp al, 0
db 0x74, 0x69 ; je 0x5a1
nop
nop
incbin "supaplex\supaplex.exe", $, 0x05c3-$ ; no PIT
db 0xb0, 0x70 ; mov al, 0x70
int 0x21
times 12 nop
incbin "supaplex\supaplex.exe", $, 0x55a5-$ ; remove mouse
retn
incbin "supaplex\supaplex.exe", $, 0x5632-$ ; use menu with backspace
db 0x80, 0x3e, 0x7b, 0x16, 0x01
incbin "supaplex\supaplex.exe", $, 0x56E2-$
in al, dx
test al, 0x8
db 0x74, 0xed
mov dx, 0x03c0
mov al, 0x33
out dx, al
db 0xA0, 0x96, 0x0D
out dx, al
int 0x70
pop ax
pop dx
ret
incbin "supaplex\supaplex.exe", $, 0x5b47-$ ; blaster.snd filesize
mov cx, 36123
incbin "supaplex\supaplex.exe", $, 0x5b7a-$ ; blaster.snd filesize
mov cx, 36123
incbin "supaplex\supaplex.exe", $, 0x8970-$ ; crack
db 0
incbin "supaplex\supaplex.exe", $, 45948-$
MOVING.DAT also has some minor imperfections in graphics, but let's fix those later...
A few other observations related to Supaplex include:
1) Supaplex needs at least 66 MHz 486 to run 70 Hz without minor tearing. Part of the reason why that much CPU power is needed is that the graphics seem to be drawn in reverse order so there's relatively speaking less time before vsync is to occur. Scrolling is "independent" so it may not tear even if sprite animation does (for example on MiSTer).
2) Music playback seems to cause minor video jerking no matter how fast a CPU (occasional duplicated frame). This jerking does not appear on the FPGA (ao486 and MiSTer FPGA) so it's probably caused by slow port operations screwing with the vertical sync (on the FPGA the port operations are much faster than on a real PC).
3) Unfortunately the FPGA is otherwise a bit too slow (minor tearing) and has some minor scrolling bug in the VGA implementation (right edge of the screen is missing varying number of pixels while scrolling). It would be nice to fix these two issues with ao486 on the FPGA at some. Proper roland CM-32L emulation would also be nice so one wouldn't need to plug in a real module (MUNT at the moment is just unusable because it's too laggy).
4) One can remove port in-based delay and the jerking is gone on the PC (works with the FPGA), but so is the music because adlib and roland are too slow and require their port delay so one needs some kind of buffering. Unfortunately my original idea of using the parallel port + arduino to do this buffering didn't quite work because the parallel port is also not quite fast enough (it helps a little compared to straight roland or adlib, but not enough).
5) I also tried rewriting the whole music routine using faster interrupts (64x 50 Hz) to get rid of port delays and use counters instead and while this worked to some degree, it causes some other timing issues with the main code which are a bit difficult to fix due to lack of game source code.
6) I also tried running the music routine during the 70 Hz vblank. That works to eliminate the jerking, but also results in the music playing way too fast.
7) Perhaps I just have to roll my own ISA card, although arduino nano doesn't have enough pins for that, at least not without some auxiliary chips, but there are alternatives.
8) I could also write the music routines natively for arduino and have them run independently of PC. That should fix any music related timing issues.
9) Or one could rewrite the whole damn game... but that's a lot of trouble...
On the PC the way to get rid of the jerking by entirely removing Programmable Interval Timer (PIT) and instead do timing with vsync. I've solved the problem of music playing too fast by skipping call to music routine 2 frames out of 7 so it plays at normal rate. SBMIDI calls are still too slow and 6+35 in's for ADLIB are too slow, but on OPL3 (SBPRO+) 1+4 in's are enough so with OPL3 we get away without any jerking on stock hardware using this 70-50 solution and SBMIDI can be replaced with my LPT2MIDI and again we get away without any jerking when dealing with the 70-50 case.
Saturday, 14 December 2019
Wednesday, 26 June 2019
Trivializing philosophy is exactly what we ought to do
Your consciousness is that part of the cosmos which correlates perfectly with what it is to experience being you. In the end it doesn't say much more than that you are what you are. It's a trivial tautology. However, all valid logical reasoning is just tautologies anyway and in the end logical conclusions are nothing more than observing the unavoidable.
It is in fact unjustified thought that existence would require a reason. The cosmic wave function may be existence itself and as such it has always existed to the extent that time exists. Its deterministic time evolution among other things corresponds to our everyday experience of movement in time, but time too is just an aspect of existence like any other. We have no examples of things beginning to exist and no examples of things ceasing to exist so there is no argument to be made about the necessity of reasons for existence.
Generally speaking, trivialising philosophy (and all problems) is exactly the goal. This is the way problems are solved. Should there be something one doesn't know which would be necessary to construct a better model, one just records this gap of knowledge waiting to be filled in the future when sufficient data becomes available and stays on track with the best data and models so far until further notice.
There's almost infinite amount of complexity associated with every question imaginable, but if anyone is to get anywhere we must act pragmatically.
It is in fact unjustified thought that existence would require a reason. The cosmic wave function may be existence itself and as such it has always existed to the extent that time exists. Its deterministic time evolution among other things corresponds to our everyday experience of movement in time, but time too is just an aspect of existence like any other. We have no examples of things beginning to exist and no examples of things ceasing to exist so there is no argument to be made about the necessity of reasons for existence.
Generally speaking, trivialising philosophy (and all problems) is exactly the goal. This is the way problems are solved. Should there be something one doesn't know which would be necessary to construct a better model, one just records this gap of knowledge waiting to be filled in the future when sufficient data becomes available and stays on track with the best data and models so far until further notice.
There's almost infinite amount of complexity associated with every question imaginable, but if anyone is to get anywhere we must act pragmatically.
Saturday, 1 December 2018
Infinite and eternal
Here I describe an approach to metaphysics based on what I call the principle of metaphysical discrimination. The goal of this principle is to focus on dividing phenomena into clear meaningful distinct categories based on the kinds of limits that can be expected to originate from the continuum between the observed nature of ones own existence and all other existence (further from self). Supernatural postulates like God, being void of predictive utility, are ignored.
We could start by trying to address the question of what is consciousness and how can it exist in a world which seemingly appears to be nothing but a Turing machine (at least to the first order), but that might be waste of time and has been more or less fruitlessly done many times before. Instead, let's start by taking for granted that something we call consciousness exists, we know this because that's us. Whichever way consciousness works, cosmos contains everything that is needed. Let us also note that there exists a kind of limitation we might call a private experience or a qualia which exists for all consciousness we are aware of. This limitation appears to prevent us from knowing what (if anything) it feels like to be someone else.
This sort of limitation resembles a phenomena of complementarity in quantum mechanics which in its simplest form is a limitation on the information any single observer can possess about certain pairs of physical observables such as position and momentum. In this context we can remain agnostic about whether these variables even have an exact simultaneous fundamental existence, and instead simply note that even if they do, the nature of our existence prevents us from ever gaining such knowledge.
The existence of this sort of complementarity in nature leads me to consider the possibility that perhaps private experience is simply another facet of all existence and ultimately no more mysterious than any other observation. Then perhaps postulating that "there is more to things" is just a kind of superstition and ultimately everything simply boils down to observing the kinds of things that exist. One could bring up the experience of time evolution of "now" as another mysterious aspect of consciousness, but time too might be nothing more than another dimension of existence.
If there in fact is nothing more to existence than existence itself (is there really an alternative?) then there can be no reason for existence. Asking for such a reason isn't even coherent, reasons are just correlations in "the set of all existence". In the spirit of Gödel's incompleteness theorems, it probably remains forever impossible to exactly prove such to be the case, but it never the less can be true and the most reasonable conclusion.
We could start by trying to address the question of what is consciousness and how can it exist in a world which seemingly appears to be nothing but a Turing machine (at least to the first order), but that might be waste of time and has been more or less fruitlessly done many times before. Instead, let's start by taking for granted that something we call consciousness exists, we know this because that's us. Whichever way consciousness works, cosmos contains everything that is needed. Let us also note that there exists a kind of limitation we might call a private experience or a qualia which exists for all consciousness we are aware of. This limitation appears to prevent us from knowing what (if anything) it feels like to be someone else.
This sort of limitation resembles a phenomena of complementarity in quantum mechanics which in its simplest form is a limitation on the information any single observer can possess about certain pairs of physical observables such as position and momentum. In this context we can remain agnostic about whether these variables even have an exact simultaneous fundamental existence, and instead simply note that even if they do, the nature of our existence prevents us from ever gaining such knowledge.
The existence of this sort of complementarity in nature leads me to consider the possibility that perhaps private experience is simply another facet of all existence and ultimately no more mysterious than any other observation. Then perhaps postulating that "there is more to things" is just a kind of superstition and ultimately everything simply boils down to observing the kinds of things that exist. One could bring up the experience of time evolution of "now" as another mysterious aspect of consciousness, but time too might be nothing more than another dimension of existence.
If there in fact is nothing more to existence than existence itself (is there really an alternative?) then there can be no reason for existence. Asking for such a reason isn't even coherent, reasons are just correlations in "the set of all existence". In the spirit of Gödel's incompleteness theorems, it probably remains forever impossible to exactly prove such to be the case, but it never the less can be true and the most reasonable conclusion.
Thursday, 22 November 2018
Conservation of etendue
Here's why you can't focus thermal light sources like the sun to a point which would get hotter than the emitting surface of the light source (omnidirectional thermal emitter). This would also violate the laws of thermodynamics. Here's what happens if you try...
...no arrangement of lenses, mirrors or any passive elements allows focusing beyond the surface temperature of the source.
Lenses and parabolic mirrors rather than purely focusing, make an image which has a minimum size that is proportional to the distance of the thermal source and the intensity lost to distance balances the sheets so that focusing alone can't result in hotter spot than the surface of the emitter.
So no matter how large a magnifying glass, even the size of earth, your spot won't get hotter than the surface of the sun. It's just equalization of temperature between two objects assisted by the magnifying glass in a way similar to bringing the objects closer to each other.
However, pure unidirectional emitters like lasers don't exactly have to obey this kind of limit. High temperature corresponds to high entropy and high disorder, whereas in terms of entropy, laser light is highly ordered, but unlike cold systems which are void of energy, laser is a kind of saturated form of energy from which energy can always flow away to increase the entropy of a typical thermodynamic system. Classical thermodynamic systems can't have this sort of state as their entropy can always increase. Only certain well isolated systems can be temporarily driven to this kind of saturated state by external source of energy.
Saturday, 3 November 2018
Small Broadcast Video Monitor for Retrogaming
Retrogaming is best experienced with CRTs. There's least amount of delay and timing and scanline reproduction is authentic. SVGA CRTs designed for 70 Hz would perhaps be the sharpest, but their phosphors are a bit too fast so they flicker with PAL (50 Hz) and NTSC (60 Hz) refresh rates a bit too much in addition to requiring at least line doubling. They don't natively support the TV-era 50/60 Hz 240p modes, but were instead operated in line doubled modes where the common game resolution of 320x200 (70 Hz) was actualy drawn as 320x400. However, some SVGA monitors can be operated at twice the refresh rate at 120 Hz and 240p giving in some ways the best result. This still isn't fully NTSC faithful as there's no way to draw the image without a frame buffer, but it never the less is good for image quality comparisons.
I recently acquired a Broadcast Video Monitor (a kind of high quality TV-style display) so I could authentically and natively view PAL/NTSC signals.
I recently acquired a Broadcast Video Monitor (a kind of high quality TV-style display) so I could authentically and natively view PAL/NTSC signals.
![]() |
| Click to enlarge. Nokia 449Xi (15" >1000 line Trinitron) with analog VGA input (RGB). The displayed resolution is single scan 320x200 at 120 Hz. |
Standard (S)VGA monitors can not be used to faithfully reproduce games such as those of Nintendo Entertainment System due to incompatible signal standards (PAL/NTSC vs. VGA). NTSC having a 15.723 kHz horizontal sync rate vs. VGA 31.46875 kHz. NTSC needs to be either line doubled or vertical scan rate doubled (or both). Doubling the vertical refresh rate would be desirable, but at the same time needs an undesirable frame buffer that adds some delay.
Difference between textmode (80x25) in 240p (60 Hz) with Sony BVM and 400p (70 Hz) SVGA monitor. VGA textmode characters are 9x16 pixels whereas in 240p the characters consist of 8x8 pixels. These correspond to resolutions 640x200 and 720x400.
A few more 240p shots perhaps less commonly from DOS games at 240p.
The monitors.
The TSRs needed for 240p 60 Hz and 120 Hz output in DOS.
Monday, 10 September 2018
Most new ideas are stupid and dangerous not unlike many old ideas, but some of the new ideas are vital and without them we're going to perish and die
The problem with reasons for causal things is that they're related to time, but causality is just an observation. Sticks don't come into existence at their tips. The tips are just an edge (of an object that exists). If the universe exists today, why would it exist tomorrow? What is the cause for the existence of tomorrow? No reason? Perhaps we should try to demonstrate that existence can never have a reason or more exactly that reasons for existence are ultimately nonsense. Then is the reason for the existence of consciousness also nonsense? Perhaps it too is just an observation about a thing that exist.
--
Why not just say that morality and values originate from our state of existence which is fundamentally arbitrary, but can be universal over a broad range of different societies to the extent that we humans share such conditions due to our evolutionary history.
--
https://codegolf.stackexchange.com/questions/11880/build-a-working-game-of-tetris-in-conways-game-of-life
--
Why not just say that morality and values originate from our state of existence which is fundamentally arbitrary, but can be universal over a broad range of different societies to the extent that we humans share such conditions due to our evolutionary history.
--
https://codegolf.stackexchange.com/questions/11880/build-a-working-game-of-tetris-in-conways-game-of-life
Saturday, 1 September 2018
If you can't do the impossible, do the honorable
Often times when I sleep, I forget that there are painful and sometimes nearly impossible things I must eventually overcome or suffer what is to come. For a moment there I feel fine, but even in my sleep, I know that when I wake up, I will forever remember what's ahead. This is the state of my being, my every waking moment short of a few most intense minutes of the year. Every time I awaken from my amnesia, the memories hit me hard. It never goes away, and almost nothing affects it.
As time is running out, my faith in a future where I'm free from that fire is slowly fading away. Time itself has shown me, things I derive value from don't appear to be going my way. This is cause my true goals have always had poor prospects within my expected lifetime, but also because I've always had extremely hard time finding comparable value in anything else. The universe may hold unimaginable wonders, but that doesn't mean I wouldn't be stuck right where I am - until the end of time. Yet I go on.
As time is running out, my faith in a future where I'm free from that fire is slowly fading away. Time itself has shown me, things I derive value from don't appear to be going my way. This is cause my true goals have always had poor prospects within my expected lifetime, but also because I've always had extremely hard time finding comparable value in anything else. The universe may hold unimaginable wonders, but that doesn't mean I wouldn't be stuck right where I am - until the end of time. Yet I go on.
Subscribe to:
Posts (Atom)




















