tgl6502: Get the romdisc fixed and as far as entering userspace
authorAlan Cox <alan@linux.intel.com>
Fri, 16 Jan 2015 23:02:22 +0000 (23:02 +0000)
committerAlan Cox <alan@linux.intel.com>
Fri, 16 Jan 2015 23:02:22 +0000 (23:02 +0000)
Kernel/platform-tgl6502/devrd.c
Kernel/platform-tgl6502/tgl6502.s

index 0361428..8766ede 100644 (file)
@@ -7,6 +7,13 @@
 #include <printf.h>
 #include <devrd.h>
 
+uint16_t romd_roff;
+uint8_t romd_rmap;
+uint8_t romd_bank;
+
+extern void __fastcall__ rd_copyin(uint16_t addr);
+
+
 static int rd_transfer(bool is_read, uint8_t rawflag)
 {
     blkno_t block;
@@ -16,15 +23,12 @@ static int rd_transfer(bool is_read, uint8_t rawflag)
     int ct = 0;
     int map;
     irqflags_t irq;
-    uint8_t old;
-    uint16_t romd_roff;
-    uint8_t romd_rmap;
 
     /* RAW won't work yet this is just an initial hack */
     if(rawflag) {
         dlen = udata.u_count;
         dptr = (uint16_t)udata.u_base;
-        if (dptr & 0x1FF) {
+        if (dptr & 0x1FF || 1 /* BROKEN */) {
             udata.u_error = EIO;
             return -1;
         }
@@ -44,13 +48,18 @@ static int rd_transfer(bool is_read, uint8_t rawflag)
         romd_roff = (block << 9);
         /* 8K block we need to select */
         romd_rmap = 0x48 + (block >> 4);
-        /* Hack for now for testing */
+        /* Map it over a page we are not copying into */
+        if (dptr >= 0xC000) {
+            romd_roff += 0xA000;
+            romd_bank = 0;
+        } else {
+            romd_roff += 0xC000;
+            romd_bank = 1;
+        }
         irq = di();
-        old = *(uint8_t *)0xFF91;
-        *(uint8_t *)0xFF91 = romd_rmap;
-        if (is_read)
-            memcpy((void *)dptr, (void *)(0xE000 + romd_roff), 512);
-        *(uint8_t *)0xFF91 = old;
+        if (is_read) {
+            rd_copyin(dptr);
+        }
         irqrestore(irq);
         block++;
         ct++;
index 688002c..63cee77 100644 (file)
@@ -35,9 +35,9 @@
            .import _unix_syscall
            .import _platform_interrupt
            .import _kernel_flag
-           .import copycommon
 
-           .import incaxy              ; from the C runtime
+           .import outcharhex
+           .import outxa
 
             .include "kernel.def"
             .include "../kernel02.def"
@@ -119,7 +119,6 @@ _program_vectors:
            ; will exit with interrupts off
            sei
            ;
-           jsr copycommon
            ; our C caller will invoke us with the pointer in x,a
            ; just pass it on
            jsr map_process
@@ -170,6 +169,9 @@ program_vectors_k:
 ;      save/restore are used so that the kernel can play with its internal
 ;      banking/mappings without having to leave interrupts off all the time
 ;
+;      ptr1 and tmp1 may be destroyed by these methods, but no other
+;      temporaries.
+;
 map_process_always:
            pha
            txa
@@ -290,12 +292,6 @@ saved_map:  .byte 0
 ; corrupting other registers
 
 outchar:
-           pha
-outcharw:
-           lda $FF01
-           and #4
-           beq outcharw
-           pla
            sta $FF03
            rts
 
@@ -371,7 +367,7 @@ syscall_entry:
            ; to the user stack we'll have finished with them
            lda sp
            ldx sp+1
-           jsr incaxy
+           jsr cincaxy
            sta sp
            stx sp+1
 
@@ -471,13 +467,19 @@ platform_doexec:
 ;
            stx ptr1+1
            sta ptr1
+
+           ldy #'E'
+           sty $FF03
+           jsr outxa
 ;
 ;      Set up the C stack
 ;
            lda U_DATA__U_ISP
            sta sp
-           lda U_DATA__U_ISP+1
-            sta sp+1
+           ldx U_DATA__U_ISP+1
+            stx sp+1
+
+           jsr outxa
 ;
 ;      Set up the 6502 stack
 ;
@@ -493,3 +495,49 @@ _unix_syscall_i:
 _platform_interrupt_i:
            jmp _platform_interrupt
 
+
+;
+;      Hack for common runtime helper (fixme move helpers to common)
+;
+cincaxy:sty tmp1
+       clc
+       adc tmp1
+       bcc incaxy2
+       inx
+incaxy2:rts
+
+;
+;      ROM disc copier (needs to be in common), call with ints off
+;
+;      AX = ptr, length always 512, src and page in globals
+;
+
+       .import _romd_bank, _romd_roff, _romd_rmap;
+       .export _rd_copyin
+
+_rd_copyin:
+       sta ptr1
+       stx ptr1+1              ; Save the target
+       ldy _romd_bank          ; 0 = A0, 1 = C0, pick based on target
+       lda $FF8F,y             ;
+       pha
+       lda _romd_rmap
+       sta $FF8F,y
+       lda _romd_roff
+       sta ptr2
+       lda _romd_roff+1
+       sta ptr2+1
+       ldy #0
+       ldx #2
+rd_cl: lda (ptr2),y
+       sta (ptr1),y
+       iny
+       bne rd_cl
+       inc ptr1+1
+       inc ptr2+1
+       dex
+       bne rd_cl
+       pla
+       ldy _romd_bank
+       sta $FF8F,y
+       rts