0000-00FF Vectors
0100-01FF Free
0200-wherever Kernel
- DB00 Discard
+ DB00 Discard (need to fix to reclaim buffers here)
E400 Common
F000 Video
- Basic initialization and setup, video and machine type probing
- Sketch of various drivers
- Basic floppy driver code
-
-To Do:
-- Floppy - media detect/sectors per track etc
- Try mounting a file system on floppy
-- Debug TC keyboard code: shift/ctrl are busted - do we need repeat ?
-- Hard disk driver debug
-- Bank the video
- Get init loading, load and test userspace
-- IDE driver (note the ubee512 emulator ide appears to be very busted as
- on 5.8.0)
- How to tell wd1010 system from 2793 from both with 0x58 switch
- Select 0x58 = 0
See if track register writes to values
*Never write 0x41 while probing as it's precomp on the WD. 0x45
however is either cyl_high or track_w so safe
+
+To Do:
+- Floppy - media detect/sectors per track etc/ hard skew
+- Debug TC keyboard code: shift/ctrl are busted - do we need repeat ?
+- Hard disk driver debug
+- Bank the video
+- IDE driver (note the ubee512 emulator ide appears to be very busted as
+ on 5.8.0)
- If we have wd1002-5 and fd wtf do we put IDE in major/minors ?
+- Non TC keyboard (lightpen keyboard)
Longer Term
- Support attributes, colour, RAM based fonts (load the ROM one into RAM
customised for bold/italic ?)
- Hardware 6x45 scrolling
- Do delayed video output via a buffer off vblank event for non premium
-- Non TC keyboard (lightpen keyboard)
- Proper support for Z80 PIO interfaces
- Z8530 SCC
- Graphics not just vt interfaces
- Maybe eventually switch to soft interrupt model and support soft serial
interrupts (ick)
+- Buffer reclaim of discard memory
Notes:
#define NUM_DEV_TTY 1
#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
#define SWAPDEV (256) /* Device for swapping (1st hd). */
-#define NBUFS 10 /* Number of block buffers */
+#define NBUFS 7 /* Number of block buffers */
#define NMOUNTS 4 /* Number of mounts at a time */
return 1;
}
-#if 0
-static uint8_t shiftmask[8] = {
- 0, 0, 0, 0, 0, 0, 0, 7
-};
-
-static void keyproc(void)
-{
- int i;
- uint8_t key;
-
- for (i = 0; i < 8; i++) {
- /* Set one of A0 to A7, and read the byte we get back.
- Invert that to get a mask of pressed buttons */
- keyin[i] = *(uint8_t *) (0xF400 | (1 << i));
- key = keyin[i] ^ keymap[i];
- if (key) {
- int n;
- int m = 1;
- for (n = 0; n < 8; n++) {
- if ((key & m) && (keymap[i] & m)) {
- if (!(shiftmask[i] & m))
- keysdown--;
- }
- if ((key & m) && !(keymap[i] & m)) {
- if (!(shiftmask[i] & m)) {
- keysdown++;
- newkey = 1;
- keybyte = i;
- keybit = n;
- }
- }
- m += m;
-
- }
- }
- keymap[i] = keyin[i];
- }
-}
-
-#endif
-
static uint8_t keymap[15];
static uint8_t keyin[15];
static uint8_t keybyte, keybit;
tty_inproc(1, c);
}
-#if 0
-void kbd_interrupt(void)
-{
- newkey = 0;
- keyproc();
- if (keysdown < 3 && newkey)
- keydecode();
-}
-
-#endif
-
__sfr __at 0x02 tc256_kstat;
__sfr __at 0x18 tc256_kcode;
if (keysdown < 3 && newkey)
keydecode_tc();
}
+
+static const uint8_t xlate[64] = {
+ '@',
+ 'a','b','c','d','e','f','g','h',
+ 'i','j','k','l','m','n','o','p',
+ 'q','r','s','t','u','v','w','x',
+ 'y','z',
+ '[','\\',']',
+ '^', KEY_DEL,
+ '0','1','2','3','4','5','6','7','8','9',
+ ':',';',',','-','.','/',
+ KEY_ESC, KEY_BS, KEY_TAB,
+ KEY_PGDOWN, KEY_ENTER, 0/*CAPSLOCK*/, KEY_STOP,
+ ' ', KEY_UP, 0/*Control*/, KEY_DOWN,
+ KEY_LEFT, 0 /* Unused */, 0 /* Unused */, KEY_RIGHT, 0/*Shift*/
+};
+
+static const uint8_t xlate_shift[64] = {
+ '@',
+ 'A','B','C','D','E','F','G','H',
+ 'I','J','K','L','M','N','O','P',
+ 'Q','R','S','T','U','V','W','X',
+ 'Y','Z',
+ '{','|','}',
+ '~', KEY_DEL,
+ /* We map _ to shift-0 */
+ '_','!','"','#','$','%','&','\'','(',')',
+ '*','+','<','=','>','?',
+ KEY_ESC, KEY_BS, KEY_TAB,
+ KEY_PGDOWN, KEY_ENTER, 0/*CAPSLOCK*/, KEY_STOP,
+ ' ', KEY_UP, 0/*Control*/, KEY_DOWN,
+ KEY_LEFT, 0 /* Unused */, 0 /* Unused */, KEY_RIGHT, 0/*Shift*/
+};
+
+/*
+ * Poll the non-TC keyboard: Need to add autorepeat once it works.
+ *
+ * On the asm side the scan needs fixing to skip ctrl, as we don't want
+ * to report ctrl as it'll hide down/left/right !
+ */
+
+uint8_t lpen_kbd_last = 0xFF;
+static uint8_t capslock;
+
+void lpen_kbd_poll(void)
+{
+ uint8_t k = kbscan();
+ /* Don't want shift/ctrl */
+ if (k != 0xFF && xlate[k]) {
+ lpen_kbd_last = k;
+ return;
+ }
+ /* Key up ? */
+ if (lpen_kbd_last == 0xFF)
+ return;
+ if (lpen_kbd_last == 53) { /* Caps lock */
+ capslock ^= 1;
+ return;
+ }
+ if (kbtest(63))
+ k = xlate_shift[k];
+ else
+ k = xlate[k];
+ if (capslock && (k >= 'a' && k <= 'z'))
+ k -= 32;
+ if (k >= 64 && k <= 127 && kbtest(57))
+ k &= 31;
+ tty_inproc(1, k);
+ lpen_kbd_last = 0xFF;
+}
extern void tty_interrupt(void);
extern void kbd_interrupt(void);
-extern int trstty_close(uint8_t minor);
+extern void lpen_kbd_poll(void);
+extern uint8_t kbscan(void);
+extern uint8_t kbtest(uint16_t code);
#endif
;
-; Core floppy routines for the TRS80 1791 FDC
+; Core floppy routines for the Microbee 2791 FDC
; Based on the 6809 code
;
; FIXME: double sided media
for the polled ports */
void platform_idle(void)
{
- __asm halt __endasm;
+ if (ubee_model == UBEE_256TC)
+ __asm halt __endasm;
+ else {
+ /* Try to make the keyboard suck as little as possible */
+ irqflags_t irq = di();
+ lpen_kbd_poll();
+ irqrestore(irq);
+ }
}
void do_beep(void)
static uint8_t icount;
uint8_t r = pia0b;
/* TODO: printer interrupt */
- /* Need to check if TC */
- if (r & 0x02)
+ if (ubee_model == UBEE_256TC && (r & 0x02))
kbd_interrupt();
if (r & 0x80) {
cmos_reg = 0x0C;
icount = 0;
}
}
+ if (ubee_model != UBEE_256TC)
+ lpen_kbd_poll();
}
}
.include "../kernel.def"
; -----------------------------------------------------------------------------
-; COMMON MEMORY BANK (0xE800 upwards)
+; COMMON MEMORY BANK (kept even when we task switch)
; -----------------------------------------------------------------------------
.area _COMMONMEM
jp to_reboot
;
-; Sit in common and play with th banks to see what we have
+; Sit in common and play with the banks to see what we have
;
size_ram:
; We could have < 128, 128 or various extensions up to 512K or
; set up the RTC driven periodic timer. The PIA should already
; have been configured for us
;
- ; we don't necessarily have one in which case we have a
- ; (arguably far more useful) vblank timer. In which case this
+ ; we don't necessarily have one. In which case this
; routine will pee into the void and do no harm whatsoever
;
ld bc,#0x0A04
ld hl, #interrupt_handler
ld (0x0039), hl
- ; set restart vector for UZI system calls
+ ; set restart vector for FUZIX system calls
ld (0x0030), a ; (rst 30h is unix function call vector)
ld hl, #unix_syscall_entry
ld (0x0031), hl
; Swap helpers
;
_hd_xfer_in:
- pop de
- pop hl
- push hl
- push de
- ld a, (_hd_page)
- or a
- call nz, map_process_a
- ld bc, #0x40 ; 512 bytes from 0x40
- inir
- inir
- call map_kernel
- ret
+ pop de
+ pop hl
+ push hl
+ push de
+ ld a, (_hd_page)
+ or a
+ call nz, map_process_a
+ ld bc, #0x40 ; 512 bytes from 0x40
+ inir
+ inir
+ call map_kernel
+ ret
_hd_xfer_out:
- pop de
- pop hl
- push hl
- push de
- ld a, (_hd_page)
- or a
- call nz, map_process_a
- ld bc, #0x40 ; 512 bytes to 0x40
- otir
- otir
- call map_kernel
- ret
+ pop de
+ pop hl
+ push hl
+ push de
+ ld a, (_hd_page)
+ or a
+ call nz, map_process_a
+ ld bc, #0x40 ; 512 bytes to 0x40
+ otir
+ otir
+ call map_kernel
+ ret
+
+;
+; Ubee Keyboard. Except for the TC the Ubee pulls this crazy (or neat
+; depending how you look at it) trick of demuxing a keyboard with the
+; lightpen input.
+;
+; See the Ubee technical manual for more information on scanning.
+;
+ .area _CODE
+
+ .globl _kbscan
+ .globl _kbtest
+ .globl _lpen_kbd_last
+;
+_kbscan:
+ ; FIXME set right register ??? or do we always put it right
+ ; irq handling versus video setup !
+ in a,(0x0C)
+ bit 6,a ; No light pen signal - no key
+ jr z, nokey ; Fast path exit
+ ld a, (_lpen_kbd_last) ; Rather than the slow scan try and
+ cp #255 ; test if we are holding down the same key
+ jr z, notlast ; assuming one was held down
+ call ispressed ; see if the key is held down (usual case)
+ ld a, (_lpen_kbd_last)
+ ; if so return the last key
+ bit 0,l ; b = 1 if we found it
+ jr nz, key_return
+notlast:
+ ld l,#57 ; Scan the keys in two banks, the first 57
+ ld de,#0x0000
+ call scanner
+ ld a,#57
+ jr nz, gotkey
+ ld l,#5
+ ld de,#0x03A0 ; and if that fails the last 5 oddities
+ call scanner ; in order to handle shift etc
+ ld a,#63
+gotkey:
+ sub b
+ jr key_return
+nokey:
+ ld a,#255
+key_return:
+ ld l,a
+ ret
+
+_kbtest:
+ pop hl
+ pop de
+ push de
+ push hl
+ ld a,e
+;
+; Check if key is currently pressed
+; Split the key by matrix position and use our scanner
+;
+ispressed:
+ rrca
+ rrca
+ rrca
+ rrca
+ ld e,a
+ and #0x0F
+ ld d,a
+ ld a,e
+ and #0xF0
+ ld e,a
+ ld l,#1
+
+;
+; Test for keys
+;
+; On entry L is the number of keys to test
+; DE is the address to scan
+;
+; Returns L holding the count of keys until we found a hit
+;
+scanner:
+ ld a,#1
+ out (0x0b),a ; character ROM so we can scan
+ ld bc,#0x130c ; for convenience
+ ld h,#31 ; port numbers used in the loop
+ ld a,#16 ; select lpen high
+ out (c),a
+ in a,(0x0d) ; clear status
+sethigh: ld a,#18 ; update register high
+ out (c),a
+ ld a,d
+ out (0x0d),a ; load passed address
+ ld a,e
+ push de ; save working address
+ ld d,#16
+setlow: out (c),b ; set the low byte from the passed address
+ out (0x0d),a
+ out (c),h ; dummy read to reset
+ out (0x0d),a
+strobe: in e,(c) ; spin for a strobe
+ jp p, strobe
+ in e,(c)
+ bit 6,e ; did we get a strobe ?
+ jr nz,scanner_done
+ dec l ; next key to test
+ jr z,scanner_done ; are we done ?
+ add a,d
+ jp nz,setlow ; next inner scan
+ pop de
+ ld e,a
+ inc d
+ jp sethigh ; next outer scan
+ ;
+ ; L holds the count remaining and thus computes the keycode
+ ; 0 means 'we found nothing'
+ ;
+scanner_done:
+ pop de ; recover position we are at
+ ld a,#16 ; lpen reset
+ out (0x0c),a
+ in a,(0x0d) ; VDU reset
+ xor a
+ out (0x0b),a
+ ret