8085: minimal optimizations for fixed bank
authorAlan Cox <alan@linux.intel.com>
Tue, 12 Mar 2019 00:18:33 +0000 (00:18 +0000)
committerAlan Cox <alan@linux.intel.com>
Tue, 12 Mar 2019 00:18:33 +0000 (00:18 +0000)
Kernel/lib/8085fixedbank-core.s [new file with mode: 0644]
Kernel/lib/8085fixedbank.s [new file with mode: 0644]

diff --git a/Kernel/lib/8085fixedbank-core.s b/Kernel/lib/8085fixedbank-core.s
new file mode 100644 (file)
index 0000000..3cfa072
--- /dev/null
@@ -0,0 +1,292 @@
+!
+!      For a purely bank based architecture this code is common and can be
+!      used by most platforms
+!
+!      The caller needs to provide the standard map routines along with
+!      map_kernel_a which maps in the kernel bank in a. This code assumes
+!      that the bank can be encoded in 8bits.
+!
+
+.sect .common
+
+.define _platform_switchout
+
+!
+!      The ABI requires we preserve BC
+!
+
+!
+!      Switch a process out and run the next one
+!
+_platform_switchout:
+       push b
+       lxi h,0
+       push h                  ! Save a 0 argment
+       lhld .retadr
+       push h
+       lhld .bcreg
+       push h
+       lhld .tmp1
+       push h
+       lhld .areg
+       push h
+       ! Do we need to save block1->block3+2 (ie do we do 32bit * and / ???
+       lxi h,0
+       dad sp
+       shld U_DATA__U_SP       ! Save the sp for a switch in
+       call map_process_always_di
+       !
+       !       Save the udata into process state
+       !
+       !       FIXME: can we skip this if the process is defunct or would
+       !       it even make sense to defer it (with magic in swapout) ?
+       !
+       lxi h,U_DATA
+       lxi d,U_DATA_STASH
+       call copy512            ! No ldir 8(
+       ! Back to kernel
+       call map_kernel_di
+       call _getproc           ! Who goes next
+       push d
+       call _switchin          ! Run it
+       ! Should never hit this
+       call _platform_monitor
+
+!
+!      Switch a process back in
+!
+.define _switchin
+
+!
+!      Switch to a given process
+!
+_switchin:
+       di
+       pop b
+       pop d                   ! DE is now our process to run
+       push d
+       push b
+
+       call map_kernel_di
+
+       !
+       !       Is it swapped (page 0)
+       !
+       lxi h,P_TAB__P_PAGE_OFFSET
+       dad d
+
+       lxi sp,_swapstack
+       mov a,m                 ! A is now our bank
+       ora a
+       jnz not_swapped
+       !
+       !       Swapping time. Interrupts back on
+       !
+       ei
+       xra a
+       sta _int_disabled
+       !
+       !       Can we rely on the compiler not mashing the stacked var ?
+       !
+       push h
+       push d
+       call _swapper
+       pop d
+       pop h
+       !
+       !       It should now be back in memory
+       !
+       mvi a,1
+       sta _int_disabled
+       di
+       mov a,m
+       !
+       !       Check if we need to recover the udata (we were last to run)
+       !
+not_swapped:
+       mov c,a
+       ! DE is the process to run, get the udata process into HL
+       lhld U_DATA__U_PTAB
+       ! See if our udata is live - this is common, if we sleep and we are
+       ! the next to run for example.
+       mov a,h
+       cmp d
+       jnz copyback
+       mov a,l
+       cmp e
+       jz skip_copyback
+       !
+       !       Recover the udata
+       !
+copyback:
+       mov a,c
+       call map_process_a
+
+       push d
+       lxi h,U_DATA_STASH
+       lxi d,U_DATA
+       call copy512
+       pop d
+
+       lhld U_DATA__U_SP       ! A valid stack to map on
+       sphl
+
+       call map_kernel
+       !
+       !       Did we find the right process ?
+       !
+       lhld U_DATA__U_PTAB
+       mov a,h
+       cmp d
+       jnz switchinfail
+       mov a,l
+       cmp e
+       jnz switchinfail
+
+skip_copyback:
+       !
+       !       Mark us as running, clear our preemption counter
+       !       and set the interrupt flags
+       !
+       lhld U_DATA__U_PTAB
+       mvi a,P_RUNNING
+       mov m,a
+       ldhi P_TAB__P_PAGE_OFFSET
+       ldax d
+       sta U_DATA__U_PAGE
+       lxi h,0
+       shld _runticks
+       lhld U_DATA__U_SP
+       sphl
+       !
+       !       Recover our parent frame pointer and return code
+       !
+       !       probably we still need to save block1-block3 (12 bytes)
+       !       used by .mli4/.dvi4. Would be good to make them do their
+       !       own saves so the cost is paid in the right place
+       !
+       pop h
+       mov a,l
+       sta .areg       ! FIXME: add a pad byte to .areg instead
+       pop h
+       shld .tmp1
+       pop h
+       shld .bcreg
+       pop h
+       shld .retadr
+       pop d
+       pop b
+       lda U_DATA__U_ININTERRUPT
+       sta _int_disabled
+       ora a
+       rnz
+       ei
+       ret
+
+switchinfail:
+       call outhl
+       lxi h,badswitchmsg
+       call outstring
+       call _platform_monitor
+
+badswitchmsg:
+       .asciz 'badsw'
+
+
+fork_proc_ptr:
+       .data2 0
+
+.define _dofork
+!
+!      The heart of fork
+!
+_dofork:
+       ldsi 2
+       lhlx
+
+       shld fork_proc_ptr
+
+       lxi d,P_TAB__P_PID_OFFSET
+       dad d
+       mov a,m
+       inx h
+       mov h,m
+       mov l,a
+       !
+       ! We don't have any state to save but the pid and framepointer 
+       ! and (alas) a pile of compiler non-reentrant crap
+       !
+       push b
+       push h
+       lhld .retadr
+       push h
+       lhld .bcreg
+       push h
+       lhld .tmp1
+       push h
+       lhld .areg
+       push h
+       lxi h,0
+       dad sp
+       shld U_DATA__U_SP
+       !
+       ! We are now in a safe state to work
+       !
+       lhld fork_proc_ptr
+       ldhi P_TAB__P_PAGE_OFFSET
+       xchg
+       mov c,m
+       lda U_DATA__U_PAGE
+
+       call bankfork
+
+       call map_process_always
+       !
+       !       Copy the parent udata and stack into the parent stash
+       !       The live udata becomes that of the child
+       !
+       lxi h,U_DATA
+       lxi d,U_DATA_STASH
+       call copy512
+
+       call map_kernel
+
+       pop h           ! Get rid of saved pid
+       pop h           ! and C runtime state
+       pop h
+       pop h
+       pop h
+
+       !
+       !       Manufacture the child udata state
+       !
+       lxi h,_udata
+       push h
+       lhld fork_proc_ptr
+       push h
+       call _makeproc
+       pop b
+       pop b
+       !
+       !       Timer ticks
+       !
+       lxi h,0
+       shld _runticks
+       !
+       !       Frame pointer
+       !
+       xchg                    ! return 0 in DE for child
+       pop b
+       ret
+
+.define bouncebuffer
+.define _swapstack
+
+bouncebuffer:
+       .space 256              ! Do we really need 256 ?
+_swapstack:
+
+.define _need_resched
+
+_need_resched:
+       .data1 0
diff --git a/Kernel/lib/8085fixedbank.s b/Kernel/lib/8085fixedbank.s
new file mode 100644 (file)
index 0000000..6c4a246
--- /dev/null
@@ -0,0 +1,45 @@
+#
+
+#include "../lib/8085fixedbank-core.s"
+
+!
+!      Fast copy 512 bytes from H to D
+!
+copy512:
+       mvi b,64
+copy8:
+       mov a,m
+       stax d
+       inx h
+       inx d
+       mov a,m
+       stax d
+       inx h
+       inx d
+       mov a,m
+       stax d
+       inx h
+       inx d
+       mov a,m
+       stax d
+       inx h
+       inx d
+       mov a,m
+       stax d
+       inx h
+       inx d
+       mov a,m
+       stax d
+       inx h
+       inx d
+       mov a,m
+       stax d
+       inx h
+       inx d
+       mov a,m
+       stax d
+       inx h
+       inx d
+       dcr b
+       jnz copy8
+       ret