“Mesolithic,” eh? When will you be publishing the Fred Flintstone version?
First thought on an interface (to use Paleolithic DROM)
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: First thought on an interface (to use Paleolithic DROM)
BruceRMcF wrote:
So now there's an Alpha V8.
“Mesolithic,” eh? When will you be publishing the Fred Flintstone version?
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: First thought on an interface (to use Paleolithic DROM)
BigDumbDinosaur wrote:
BruceRMcF wrote:
So now there's an Alpha V8.
“Mesolithic,” eh? When will you be publishing the Fred Flintstone version?
I've just been trying to squeeze out a couple of bytes here and there to get room to add a backspace function of sorts to his original two function code. I thought I had fallen short at the line, but then I saw a way to squeeze out two more bytes, so I've been able to fall over the finish line after all.
The backspace function is actually a pair of functions, one in case the code is at a page boundary, since the normal one would wrap at the page boundary ... but for someone learning on a trainer like this, I reckon learning about 6502 hardware not doing the adjustments at page boundaries for you is a reasonable thing to learn.
Re: First thought on an interface (to use Paleolithic DROM)
Meanwhile, I discovered this afternoon that Paleolithic DROM had the wrong footprint for the diodes: SOD323 instead of SOD123 (which is why the solder pads were so tiny). Unfortunately, a global footprint change zapped everything; a complete board layout is in hand
Bruce is going way too fast for me! I want to send both boards out at the same time, so I need to finish those first, but I'd like to single step Bruce's code (and possibly my original code, just to see if it works!) before I start soldering around five hundred diodes (anyone know the ratio of ones to zeros in generic 6502 code?).
But yes, Neolithic for new stone age for my generic 6502 stuff; Paleolithic old stone age for the diode rom, and Mesolithic for this because it's somewhere in the middle between the two
Neil
Bruce is going way too fast for me! I want to send both boards out at the same time, so I need to finish those first, but I'd like to single step Bruce's code (and possibly my original code, just to see if it works!) before I start soldering around five hundred diodes (anyone know the ratio of ones to zeros in generic 6502 code?).
But yes, Neolithic for new stone age for my generic 6502 stuff; Paleolithic old stone age for the diode rom, and Mesolithic for this because it's somewhere in the middle between the two
Neil
Re: First thought on an interface (to use Paleolithic DROM)
barnacle wrote:
... Bruce is going way too fast for me! ...
Since these are not my assembler's mnemonics, I haven't been doing the usual assembling as I go to do the byte counting for me, so there could always be a blunder in the byte counting, but I'm hoping the one miscount I caught last week was the last one left.
Re: First thought on an interface (to use Paleolithic DROM)
For the Mesolithic micro-monitor, I've been looking at getting rid of polling for release, which will glitch the LED's. The idea I've been working on is executing the key the first time a key is pressed, and also setting up "key pressed" mode, so until the key pressed state is reset, the key is not executed again.
I'm also including an opportunity for a touch of software debouncing, in requiring a couple of consecutive releases detected before resetting the key pressed state.
This is in the context of cycling through all eight LEDs, since there is enough room to initialize the values of the upper LEDs to zero. Rather than counting consecutive presses in the detected key column, every key detected restarts the count, and the count is of consecutive "non-key" returns. SO after a key press, 8 cycles later the routine is back at the same key column, 16 cycles later it has passed through the same key column twice. So if the count passes from 0 to 16 ($10), it is treated as two releases detected in the pressed key's column, and the key pressed mode is reset.
Bit 7 of "mflags" (mode-flags) is used for Break mode, so Bit 6 is "key-pressed" mode and bits 0-5 are available for the count. In the code, using a bit test for the count, the count limit has to be a power of 2, but in addition to the minimal value of 8, and the default of 16, 32 (4 consecutive key-releases) is also available if the hardware debounce needs the extra leeway on the release.
Also, with the use of "trb" and "tsb" requiring access to register A, I noted that the key is used in Comparisons at the outset. Then, if a hex key, it is stored in a temporary zero page location to be combined with the previous low nybble that has been rotated into the top nybble. And so the key is read into the X register:
So the "not a key" read has three possibilities.
Now, if an app borrowing this as it's keyboard read by using the application side 16-function vector has a routine that lasts too long, the LEDs will still glitch or dim, but in regular micro-monitor use, it seems like the execution time of the key routines will be dominated by the set up of the leds vector in each digit loop to be roughly similar in length.
This is looking to be coming in at a page and a half image to punch into the application memory, plus the routine to write it to an EEPROM. I've also got some 32 bytes of various LED segment definitions ... bouncing ball, rotator for bottom half, rotator for top half, rotator for full LED, some scattered Letters and math symbols, available to be included in the free bottom half of $FExx.
I'm also including an opportunity for a touch of software debouncing, in requiring a couple of consecutive releases detected before resetting the key pressed state.
This is in the context of cycling through all eight LEDs, since there is enough room to initialize the values of the upper LEDs to zero. Rather than counting consecutive presses in the detected key column, every key detected restarts the count, and the count is of consecutive "non-key" returns. SO after a key press, 8 cycles later the routine is back at the same key column, 16 cycles later it has passed through the same key column twice. So if the count passes from 0 to 16 ($10), it is treated as two releases detected in the pressed key's column, and the key pressed mode is reset.
Bit 7 of "mflags" (mode-flags) is used for Break mode, so Bit 6 is "key-pressed" mode and bits 0-5 are available for the count. In the code, using a bit test for the count, the count limit has to be a power of 2, but in addition to the minimal value of 8, and the default of 16, 32 (4 consecutive key-releases) is also available if the hardware debounce needs the extra leeway on the release.
Also, with the use of "trb" and "tsb" requiring access to register A, I noted that the key is used in Comparisons at the outset. Then, if a hex key, it is stored in a temporary zero page location to be combined with the previous low nybble that has been rotated into the top nybble. And so the key is read into the X register:
Code: Select all
; +34
; for each LED digit (right to left)...
lda leds,y
sta led_addr,y ; display bit pattern
ldx keys
bpl loop_key
; Not a key
; if the state is unpressed, nothing to do
bit mflags
bvc loop_99
; if the state is pressed, increment the count
; test for hitting relcnt_n (release count "N")
inc mflags
lda #relcnt_n
trb mflags
beq loop_99 ; not at release count yet
lda #press_reset ; $7F = %01111111
trb mflags
bra loop_99 ; reset pressed state
; resets count as well - If in "released" mode, bit6=0, there's nothing to do, go do the next LED column.
- If in pressed mode, increment the count, and see if it overflows into the "release count 'N'" bit. If not, go do the next LED column. "N" has to be either 1, 2 or 4 consecutive releases, as 8, 16 or 32 consecutive non-keys read in the column cycle. To push it higher, have a separate byte in the zero page for a countdown multiple of eight that is restored every time a key is detected, decrement in a column with no key detected, and reset to released mode when the count hits 0, which supports requiring an arbitrary 1 to 31 consecutive releases before resetting to released mode.
- If in pressed mode and it overflows into the release count, reset into "released" mode. Since it should be detected when all lower bits are zero, testing for hitting the release count with "trb" ought to have reset the release count, but it's free to just reset all of the count field bits alongside resetting the "pressed key" bit.
Code: Select all
loop_key:
lda #pressbit ; bit 6, $40 = %01000000
tsb mflags ; use BOTH "test bit" & "set bit"
beq loop_1stkey ; if reset before, 1st key
lda #countfield ; otherwise reset release count
trb mflags ; %0011111111 to leave pressed state alone
bra loop_99
loop_1stkey:
; do stuff to sort out the key value
; a hex key if below smallest command code
; above, set up to be KEY_GO
cpx #KEY_GO
bmi loop_hex ; enter hex value
beq exec ; jump punched in code
cpx #KEY_BS ; test 2nd largest command code
beq loop_bspace ; decrement memptr
bpl function ; perform function
; using low nybble showing
; +12
; remaining special key is return
; accept current byte value, increment memptr
inc memptr
bne getdata
inc memptr+1
getdata: ; used by functions that change memptr
lda (memptr)
sta data
bra loop_90
loop_hex: ; +12
; else shuffle key value into (memptr)
; In this version, d7=/Press
; d7 clear if hex key
lda (memptr)
asl a
asl a
asl a
asl a
stx temp
ora temp
sta (memptr)
loop_90: ; +0
; This has been removed
; ; wait for key to be released
; ; this will cause display glitch, but...
; lda keys
; bmi loop_90
loop_99: ; +5
dey
bpl loop_digit
bra loop_main This is looking to be coming in at a page and a half image to punch into the application memory, plus the routine to write it to an EEPROM. I've also got some 32 bytes of various LED segment definitions ... bouncing ball, rotator for bottom half, rotator for top half, rotator for full LED, some scattered Letters and math symbols, available to be included in the free bottom half of $FExx.
Re: First thought on an interface (to use Paleolithic DROM)
Well, now we wait a few days... twenty bucks for the PCBs for Meso and Paleo, thirty bucks for components (bumped up by minimum quantities, naturally) from LCSC, and $1.42 from Mouser - who had one critical chip in the right package that LCSC didn't have. I might have bulked out the order with things for the cupboard - spare processor, some memory, you know kind of thing 
I bought fifteen hundred diodes so my memory is point nine of a cent per bit (that isn't there; it's the zeros that need the diodes).
Neil
I bought fifteen hundred diodes so my memory is point nine of a cent per bit (that isn't there; it's the zeros that need the diodes).
Neil
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: First thought on an interface (to use Paleolithic DROM)
barnacle wrote:
I might have bulked out the order with things for the cupboard - spare processor, some memory, you know kind of thing 
Might have? Uh-huh.
That has been known to happen at times when I order parts. Somehow, I ended up with a bag full of BAT85 Schottky diodes...about a thousand of those little suckers.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: First thought on an interface (to use Paleolithic DROM)
I guess on average, it will take about five hundred diodes to fill out all the requisite zeros. On the other hand, back in the 1950s, core memory was about a (1950) dollar a byte... I wonder how much magnetic core loops are these days?
Re: First thought on an interface (to use Paleolithic DROM)
Bruce... V8 is one byte too long 
There are eleven bytes here...
Fixed a couple of mis-named loops and a > instead of 'hi' to make it compile, but it complained about an org that goes backwards
Neil
Code: Select all
; then update LED and get key
; +10
ff99 : b9fa00 lda leds,y
ff9c : 990098 sta led_addr,y ; display bit pattern
ff9f : ad0090 lda keypad
; d7=NOR(row1,row2,row3,row4,row5)
ffa2 : 302b bmi loop_99 ; no key pressed
Fixed a couple of mis-named loops and a > instead of 'hi' to make it compile, but it complained about an org that goes backwards
Neil
Re: First thought on an interface (to use Paleolithic DROM)
barnacle wrote:
Bruce... V8 is one byte too long 
There are eleven bytes here...
Fixed a couple of mis-named loops and a > instead of 'hi' to make it compile, but it complained about an org that goes backwards
Neil
Code: Select all
; then update LED and get key
; +10
ff99 : b9fa00 lda leds,y
ff9c : 990098 sta led_addr,y ; display bit pattern
ff9f : ad0090 lda keypad
; d7=NOR(row1,row2,row3,row4,row5)
ffa2 : 302b bmi loop_99 ; no key pressed
Fixed a couple of mis-named loops and a > instead of 'hi' to make it compile, but it complained about an org that goes backwards
Neil
I'll sidestep high byte operators by having the high byte in the equates. Let me know the misnamed loops & I'll fix them in the base source as well.
11ty bytes? Oh, of course ... X could hold the column when the leds segment writer was outside of the digit loop, reverting back to ,y is three bytes even in zero page.
Back to the wonkier version. Backspace wraps on page boundary, if there's a mistake or a key bounce that is behind a page boundary, make a note and fix it up in another pass, with "+" giving that restart at $0200.
Re: First thought on an interface (to use Paleolithic DROM)
The break point support I've got sketched out relies on storing data in dedicated space high in the zero page, having a function to go to the first byte in that space (rega), and having a return from break function that executes if in break mode, is a dead key if not in break mode:
The high bit of the mflags byte in zero page is the Break Mode flag. Note that the premise is that if there are IRQ's set-up, a more full fledged set-up is required, so it is assumed that only breakpoints trigger the BRK/IRQ vector.
Note that a Break here is a "two byte" BRK, with a marker byte, to use RTI rather than also storing the BRK return in its own vector location and using JMP (brkvector) to return from the BRK.
"wmstart" jumps into the Reset start up after the memptr has been set-up:
Down in the "+" key functions is "showreg":
"getdata" is the stage in the CR function after the mempr vector has been incremented, when the byte originally at that location is stashed into the zero page for the 3 functions which use the "current" contents of memptr for some other use (high address byte, low address byte, and function key).
Then because the stack was restored after the break information was pulled off, as long as the system is in BRK mode, returning from Break is loading whatever is in the "register" shadow locations and executing an RTI:
Code: Select all
org $fe70
break: ; +23
sta rega
stx regx
sty regy
tsx
pla
sta regflags
pla
sta memptr
pla`
sta memptr+1
txs
lda #$80
tsb mflags ; use BREAK "+" functions
bra wmstart Note that a Break here is a "two byte" BRK, with a marker byte, to use RTI rather than also storing the BRK return in its own vector location and using JMP (brkvector) to return from the BRK.
"wmstart" jumps into the Reset start up after the memptr has been set-up:
Code: Select all
; "F+" showapp function starts here
showapp:
start: ; +12
; Set base address, this is also "showapp"
lda #addr0hi
sta memptr+1
stz memptr ; start at page aligned addr0
wmstart:
lda (memptr)
sta data
... Code: Select all
showregs: ; +8
stz memptr+1
lda #rega
sta memptr
bra getdata Then because the stack was restored after the break information was pulled off, as long as the system is in BRK mode, returning from Break is loading whatever is in the "register" shadow locations and executing an RTI:
Code: Select all
brkrtn: ; +13
lda #$80
trb mflags ; turn off BRK mode
beq loop_90 ; wasn't BRK mode
lda rega
ldx regx
ldy regy
rti Re: First thought on an interface (to use Paleolithic DROM)
Frank Kingswood's AS65. It takes (also) C-style numeric indicators, 0b as a prefix for binary patterns.
The misnamed loops are 'keys' in line 84 and 129, should be 'keypad', and 'loop' at line 111, should be 'loop_digit' (I think).
This one builds fine; just starting to test. To use it with Symon, I'll need to move keypad to $7000 and led_addr to 7080 so I can see what's going on; I'll also change the LED patterns to give ascii values, for the same reason.
To avoid confusion (mine) - your most recent post is for a monitor which might for example be keyed in using Paleo, not part of Paleo itself, right?
Neil
The misnamed loops are 'keys' in line 84 and 129, should be 'keypad', and 'loop' at line 111, should be 'loop_digit' (I think).
This one builds fine; just starting to test. To use it with Symon, I'll need to move keypad to $7000 and led_addr to 7080 so I can see what's going on; I'll also change the LED patterns to give ascii values, for the same reason.
To avoid confusion (mine) - your most recent post is for a monitor which might for example be keyed in using Paleo, not part of Paleo itself, right?
Neil
Re: First thought on an interface (to use Paleolithic DROM)
barnacle wrote:
...
To avoid confusion (mine) - your most recent post is for a monitor which might for example be keyed in using Paleo, not part of Paleo itself, right? ...
To avoid confusion (mine) - your most recent post is for a monitor which might for example be keyed in using Paleo, not part of Paleo itself, right? ...
It ought to be possible to raid a couple of the features of the the M^3 (MesolithicMicroMonitor) for a patch of well under half a page to support the customizable "+" function call interface being available to what is primarily a copy of the DROM code.
That is because the area just underneath the DROM code from $FF80-$FFFF is well within half a binary page of the calls to execute "Go", "CR", "-" and "+", and the targets after those functions are completed are also with half a binary page, so writing new patch targets for those instead of the original target would allow otherwise using the existing DROM code, so only six addresses would have to be checked for patching while copying the DROM code into an EEPROM.
This would be a "freestanding" development activities path ... I presume another path is to use the DROM to punch in a sufficient terminal to support downloading an EEPROM image over the serial port, which is a lane that I will be watching with interest if it eventuates.
Re: First thought on an interface (to use Paleolithic DROM)
I have not yet tested Bruce's version, but here's a slightly modified version of my original thoughts (from which Bruce's is largely taken) and including a couple of Bruce's points. It includes definitions to let it run on the Symon simulator in 'Symon' mode. It also includes what I think is a half millisecond delay in one byte; check around loop_91 and loop_92... after it builds the character versions in zero page to output to the LEDs, x = 2, and from there it counts up. However, if by some chance of providence, x does not equal zero after a reset, it's potentially going to thump eight random bytes of zero page depending on x, which is not ideal.
Without that delay, there are currently six bytes free. I haven't included Bruce's + and - functionality yet until I know whether the delay is required (LEDs are very fast and will certainly turn hard on in a microsecond, but I'm not sure if the eye actually sees that at a sensible brightness. I need to play.)
[0] VBIOS = Very Basic IO System
Neil
Without that delay, there are currently six bytes free. I haven't included Bruce's + and - functionality yet until I know whether the delay is required (LEDs are very fast and will certainly turn hard on in a microsecond, but I'm not sure if the eye actually sees that at a sensible brightness. I need to play.)
Code: Select all
; Mesolithic VBIOS to be loaded on Paleolithic DROM
keys equ $7000 ; for Symon equ $9000 ; for Meso
led_addr equ $7080 ; for Symon equ $9800 ; for Meso
RUN equ $10
RETURN equ $11
bss
org 0
leds ds 8 ; led will display patterns stored here
mem_ptr ds 2 ; where are we writing?
temp ds 1 ; temporary store to combine keypad hex
code
org $c000
db 0 ; keep symon happy
org $ff80
;LED_PATTERNS db 0b00111111 ;0 ; for Meso
; db 0b00000110 ;1
; db 0b01011011 ;2
; db 0b01001111 ;3
; db 0b01100110 ;4
; db 0b01101101 ;5
; db 0b01111101 ;6
; db 0b00000111 ;7
; db 0b01111111 ;8
; db 0b01101111 ;9
; db 0b01110111 ;A ; changed to capital
; db 0b00111100 ;b
; db 0b00111001 ;C ; changed to capital
; db 0b01011110 ;d
; db 0b01111001 ;E ; changed to capital
; db 0b01110001 ;F ; changed to capital
; changed for Symon to show more simply in the memory view
LED_PATTERNS db '0123456789abcdef'
start:
lda #2
sta mem_ptr+1
stz mem_ptr ; start address $200
loop_0:
ldy #5 ; we have eight leds but we only need to drive six
; (saves code space)
loop:
; for each character...
lda leds,y
sta led_addr,y ; display bit pattern
lda keys
bmi loop_91 ; bit 7 clear if key pressed so we can directly
; read a valid key value
; if key value = return
cmp #RETURN
bne loop_2
; increment memory address pointer
inc mem_ptr
bne loop_90
inc mem_ptr+1
bra loop_90
; endif
loop_2:
; if key value = go
cmp #RUN
bne loop_3
; execute the program
jmp $200
; endif
loop_3:
; else shuffle key value into (mem_ptr)
sta temp
lda (mem_ptr)
asl a
asl a
asl a
asl a
ora temp
sta (mem_ptr)
loop_90:
; wait for key to be released
; this will cause display glitch, but...
lda keys
bpl loop_90
loop_91:
; put mem_ptr and (mem_ptr) into leds
; [x][x][x][x][x][x][ ][ ]
; (also provides a short delay for the LED multiplex)
ldx #0
lda mem_ptr+1
jsr to_leds
lda mem_ptr
jsr to_leds
lda (mem_ptr)
jsr to_leds
loop_92: ;optional delay between LED cycles
; stretches the illumination time for each LED to approx
; half a millisecond
; if used, ldx after loop_91 can be deleted
; inx
; bne loop_92
; update the display count
dey
bpl loop
bra loop_0
to_leds:
; unpack byte into two adjacent LED patterns
; x has character position
phy
pha
and #$0f ; low nibble
tay
lda LED_PATTERNS,y ; index into the patterns
sta leds+1,x ; and output into the LED array
pla
lsr a
lsr a
lsr a
lsr a ; high nibble
tay
lda LED_PATTERNS,y
sta leds,x ; this byte goes on the left
inx
inx
ply
rts
org $fffc
dw start
dw start
Neil