home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / BEEHIVE / OS / SUPER8.ARC / FORTH.S8 next >
Text File  |  1990-09-21  |  8KB  |  446 lines

  1. ;--------------------------------------------------------
  2. ; FORTH for the Super8
  3. ; jdw 2/87
  4. ;
  5. ; Working register assignment:
  6. ;
  7. ; rr0     datastack
  8. ; rr2    registered top of stack
  9. ; rr4    temp, SP on task switch
  10. ; rr6    temp
  11. ;
  12. ; rr8    registered DO index 
  13. ; rr10    registered DO terminal count
  14. ; rr12  registered LOOP jp address  
  15. ; rr14    user base
  16. ;----------------------------------------------------------------
  17. ; Multi-tasking:
  18. ;
  19. ;  A task's context is contained in 16 working registers.  Changing
  20. ; RP0 & RP1 effects a context switch.  Tasks use consecutive 16 byte
  21. ; register sets starting at 0.  The register <tskptr>  points to the
  22. ; highest set in use (0 for one task).   Reserving 16 bytes for system
  23. ; registers (such as tskptr), a maximum of 15 tasks could run.
  24. ;
  25. ; Note that killing off a  task other than the last requires that the 
  26. ; registers used by the last task be copied into the task to be killed.
  27. ; A new task is always added at <tskptr+16>
  28. ;
  29. ;  It is not decided how much gain there would be in registering
  30. ; a few more things, such as do loop index and count.
  31. ;-----------------------------------------------------------------
  32. ; Note: monitor uses $FB00-$FFFF and reg $80-$B9
  33. ;-----------------------------------------------------------------
  34. ; Note: in register pairs, the low register is the high byte!
  35. ; I.E. top of stack, r2= high, r3 = low.  The same is true for 
  36. ; memory organization!
  37. ;
  38.     org    $C000
  39. flgs    equ    $C300
  40.  
  41. tskptr    equ    $7F    ; higest task  register
  42.  
  43. ukey?    equ    0    ; user variables
  44. ukey    equ    2
  45. uemit    equ    4
  46.  
  47.  
  48. test:    sb0
  49.     ld    emt,#%00000011    ; 1 wait, data stack, data dma
  50.  
  51.     srp    #0        ; set up RP0 and RP1
  52.     ldw    rr0,#$F800    ; set up dstack
  53.     ldw    sp,#$F000
  54.     ldw    rr2,#0
  55. ;---------------------------------------------------
  56. ; Sieve benchmark,  6.81s/10 iterations
  57.  
  58. size    equ    8190
  59.  
  60.     enter        ; brenchmark starts here
  61.     dw    adotq
  62.     .ascil    "start\n"
  63.     dw    lit,10
  64.     dw    zero
  65.     dw    do
  66.     dw    prime
  67.     dw    loop
  68.     dw    adotq
  69.     .ascil    "stop\n"
  70.     dw    pbrk
  71.     
  72. pbrk:    jr    $
  73.     nop
  74. prime:    enter        ; sieve benchmark
  75.     dw    lit,flgs
  76.     dw    lit,size
  77.     dw    one
  78.     dw    fill
  79.     dw    zero
  80.     dw    lit,size
  81.     dw    zero
  82.  
  83.     dw    do
  84.     dw    ficf,prime1    ; FLAGS I + C@ IF
  85.     dw    op1        ; i dup plus 3 + dup i +
  86.     dw    begin
  87.     dw    op2,prime2    ; WHILE
  88.     dw    caf        ; 0 over flags + c!
  89.     dw    over, plus
  90.     dw    again
  91. prime2:    dw    xwhile
  92.     dw    ddrop
  93.     dw    onep
  94. prime1:    dw    loop
  95.     dw    exit
  96.  
  97. ; Sieve benchmark primitive,  FLAGS I + C@ IF
  98.  
  99.  
  100. ficf:    lde    r4,flgs(rr8)    ; 20  get the flag
  101.     btjrt    ficf1,r4,#0    ; 10/12 if the flag was = 1, do not jump
  102.     ldw    rr4,ip
  103.     lde    r6,@rr4
  104.     lde    r7,1(rr4)
  105.     ldw    ip,rr6
  106.     next
  107. ficf1:    incw    ip        ; 10
  108.     incw    ip
  109.     next            ; 14
  110.  
  111.  
  112. caf:    ; same as    0 over flgs + c!
  113.     ; stack:  (index--index)
  114.  
  115.     ld    r4,#0
  116.     ldc    flgs(rr2),r4    ; clear it
  117.     next
  118.  
  119. op1:    ; i dup + 3 +  dup i +
  120.     ; ( --2i+3,3i+3)
  121.  
  122.     ldepd    @rr0,r3    ; push tos
  123.     ldepd    @rr0,r2
  124.     ldw    rr2,rr8    ; I
  125.     add    r3,r9
  126.     adc    r2,r8    ; 2I
  127.     add    r3,#3
  128.     adc    r2,#0    ; 2I+3
  129.     ldepd    @rr0,r3    ; push 2I+3
  130.     ldepd    @rr0,r2
  131.     add    r3,r9
  132.     adc    r2,r8    ; 3I+3
  133.     next
  134. ;----------
  135. op2:    ; dup size less if
  136.  
  137.     ldw    rr4,rr2
  138.     sub    r5,#^LB size
  139.     sbc    r4,#^HB size
  140.     jp    pl,branch    ; if tos >= size, take branch
  141.     incw    IP
  142.     incw    IP
  143.     next
  144.  
  145.  
  146. ;--------------------------------------------------
  147. ZERO:    ldepd    @rr0,r3    ; 46 clocks
  148.     ldepd    @rr0,r2
  149.     ldw    rr2,#0
  150.     next
  151.  
  152. ONE:    ldepd    @rr0,r3    ; 46 clocks
  153.     ldepd    @rr0,r2
  154.     ldw    rr2,#1
  155.     next
  156.  
  157. ONEP:    incw    rr2    ; 26
  158.     next
  159.  
  160. TWO:    ldepd    @rr0,r3
  161.     ldepd    @rr0,r2
  162.     ldw    rr2,#2
  163.     next
  164.  
  165. THREE:    ldepd    @rr0,r3
  166.     ldepd    @rr0,r2
  167.     ldw    rr2,#3
  168.     next
  169.  
  170. ;------------------------------------------
  171. LESS:    ldei    r4,@rr0
  172.     ldei    r5,@rr0
  173.     sub    r5,r3
  174.     sbc    r4,r2    ; rr4-rr2
  175.     ldw    rr2,#0
  176.     jr    pl,next    ; if tos (rr2) > nos, return false
  177.     inc    r3    ; else true
  178. next:    next
  179.  
  180. ADOTQ:    enter        ; <.">  print imbeded string
  181.     dw    RAT
  182.     dw    COUNT
  183.     dw    DUP
  184.     dw    ONEP
  185.     dw    FROMR
  186.     dw    PLUS
  187.     dw    TOR
  188.     dw    TYPE
  189.     dw    EXIT
  190.  
  191. C!:    incw    rr0    ; address = rr2
  192.     ldei    r5,@rr0    ; get data
  193.     lde    @rr2,r5 ; stash byte
  194.     ldei    r2,@rr0
  195.     ldei    r3,@rr0
  196.     next
  197.  
  198. C@:    lde    r3,@rr2
  199.     clr    r2
  200.     next
  201.  
  202. CMOVE:    ldei    r4,@rr0    ; count in RR2
  203.     ldei    r5,@rr0    ; des to rr4
  204.     ldei    r6,@rr0
  205.     ldei    r7,@rr0    ; src to rr6
  206.     incw    rr2
  207.     decw    rr2
  208.     jr    z,cmove1 ; if count = 0
  209.     push    r0
  210. cmv1:    ldei    r0,@rr6     ; read 1 byte
  211.     lde    @rr4,r0     ; write 1 byte
  212.     incw    rr4
  213.     decw    rr2
  214.     jr    nz,cmv1
  215.     pop    r0
  216. cmove1:    ldei    r2,@rr0    ; 46 clocks
  217.     ldei    r3,@rr0    ; low byte
  218.     next
  219.  
  220.  
  221. COUNT:    ldei    r4,@rr2    ; count byte
  222.     ldepd    @rr0,r3
  223.     ldepd    @rr0,r2
  224.     ld    r3,r4
  225.     clr    r2
  226.     next
  227.  
  228. DDROP:    incw    rr0
  229.     incw    rr0
  230. DROP:    ldei    r2,@rr0    ; 46 clocks
  231.     ldei    r3,@rr0    ; low byte
  232.     next
  233.  
  234. DUP:    ldepd    @rr0,r3    ; 46 clocks
  235.     ldepd    @rr0,r2
  236.     next
  237.  
  238. FILL:    ldei    r4,@rr0        ; character in RR2 (r3)
  239.     ldei    r5,@rr0        ; count to rr4
  240.     ldei    r6,@rr0
  241.     ldei    r7,@rr0        ; src to rr6
  242.     incw    rr4
  243.     decw    rr4
  244.     jr    z,FL1        ; if count = 0
  245. FL2:    lde    @rr6,r3        ; write 1 byte
  246.     incw    rr6
  247.     decw    rr4
  248.     jr    nz,FL2
  249. FL1:    ldei    r2,@rr0
  250.     ldei    r3,@rr0
  251.     next
  252.  
  253. EXIT:    exit
  254.  
  255. PLUS:    ldei    r4,@rr0    ; 58
  256.     ldei    r5,@rr0
  257.     add    r3,r5
  258.     adc    r2,r4
  259.     next
  260.  
  261.  
  262. OVER:    ldepd    @rr0,r3
  263.     ldepd    @rr0,r2
  264.     lde    r2,2(rr0)
  265.     lde    r3,3(rr0)
  266.     next
  267.  
  268. RAT:    ldepd    @rr0,r3    ; R@
  269.     ldepd    @rr0,r2
  270.     ldw    rr4,sp
  271.     ldei    r2,@rr4
  272.     lde    r3,@rr4
  273.     next
  274.  
  275. FROMR:    ldepd    @rr0,r3    ; R>
  276.     ldepd    @rr0,r2
  277.     pop    r2
  278.     pop    r3
  279.     next
  280.  
  281. TOR:    push    r3    ; >R
  282.     push    r2
  283.     ldei    r2,@rr0
  284.     ldei    r3,@rr0
  285.     next
  286.  
  287.  
  288. SWAP:    lde    r4,@rr0    
  289.     lde    r5,1(rr0)
  290.     lde    @rr0,r2
  291.     lde    1(rr0),r3
  292.     ld    r2,r4
  293.     ld    r3,r5
  294.     next
  295.  
  296.  
  297. TYPE:    enter
  298.     dw    zero
  299.     dw    do
  300.     dw    dup
  301.     dw    c@
  302.     dw    emit
  303.     dw    onep
  304.     dw    loop
  305.     dw    drop
  306.     dw    exit
  307.  
  308. ;---------------------------------
  309. ; Do loop, registered I
  310. ;
  311. ; 5.0 us (9.0 every 256'th)
  312. ; loop + i =  10.6
  313. ;
  314. do:    push    r13
  315.     push    r12
  316.     push    r11
  317.     push    r10
  318.     push    r9        ; save old loop registers
  319.     push    r8
  320.  
  321.     ldw    rr12,ip        ; branch address to rr12
  322.     ldw    rr8,rr2        ; index to rr8
  323.     ldei    r10,@rr0    
  324.     ldei    r11,@rr0    ; TC to rr10
  325.     ldei    r2,@rr0        ; refresh tos
  326.     ldei    r3,@rr0    
  327.     next
  328.  
  329. loop:    incw    rr8    ; 10 bump I
  330.     cp    r9,r11    ; 6
  331.     jr    z,lp1    ; 10
  332.     ldw    ip,rr12    ; 10
  333.     next        ; 14
  334. lp1:    cp    r8,r10    ; 6
  335.     jr    z,lp2    ; 10
  336.     ldw    ip,rr12    ; 10
  337.     next        ; 14
  338. lp2:    pop    r8
  339.     pop    r9
  340.     pop    r10    ; restore loop registers
  341.     pop    r11
  342.     pop    r12
  343.     pop    r13
  344.     next
  345.  
  346. ;--------------------------------------
  347. ; Registered I,  5.6 us
  348.  
  349. i:    ldepd    @rr0,r3    ; 16    ; push tos
  350.     ldepd    @rr0,r2    ; 16
  351.     ldw    rr2,rr8    ; 10
  352.     next        ; 14
  353. ;------------------------------------
  354. dovar:    ; called version, 7.4us
  355.     ; CALL is 18
  356.  
  357.     ldepd    @rr0,r3    ; 16    ; push tos
  358.     ldepd    @rr0,r2    ; 16
  359.     ldw    rr2,@SP    ; 10
  360.     next        ; 14
  361. ;--------------------------------------------------------
  362. emit:    tm    utc,#2        ; transmit buffer empty yet?
  363.     jr    z,emit        ; if not, wait until it is
  364.     ld    uio,r3        ; load the character into the transmitter
  365.     ldei    r2,@rr0        ; get new TOS
  366.     ldei    r3,@rr0        ; low byte
  367.     next
  368.  
  369. key:    tm    urc,#1        ; character available?
  370.     jr    z,key        ; if not, wait until it is
  371.     ldepd    @rr0,r3        ; push old tos
  372.     ldepd    @rr0,r2
  373.     ld    r3,uio        ; the character
  374.     cp    r3,#4
  375.     jp    z,$20        ; control D abort
  376.     clr    r2
  377.     next
  378.  
  379. clit:    ldepd    @rr0,r3        ; Imbeded byte literal
  380.     ldepd    @rr0,r2
  381.     ldw    rr4,ip
  382.     lde    r3,@rr4        ; low byte
  383.     clr    r2
  384.     incw    ip
  385.     next
  386.  
  387. lit:    ldepd    @rr0,r3        ; Imbeded literal
  388.     ldepd    @rr0,r2
  389.     ldw    rr4,ip
  390.     ldei    r2,@rr4        ; hi byte
  391.     ldei    r3,@rr4        ; low byte
  392.     ldw    ip,rr4
  393.     next
  394.  
  395.  
  396. branch:    ldw    rr4,ip
  397.     lde    r6,@rr4
  398.     lde    r7,1(rr4)
  399.     ldw    ip,rr6
  400.     next
  401.  
  402. zbran:    or    r2,r3    ; test for zero
  403.     ldei    r2,@rr0    ; pop tos
  404.     ldei    r3,@rr0
  405.     jr    nz,skip
  406.     ldw    rr4,ip    ; take the branch
  407.     lde    r6,@rr4
  408.     lde    r7,1(rr4)
  409.     ldw    ip,rr6
  410.     next
  411. skip:    incw    ip
  412.     incw    ip
  413.     next
  414.  
  415. begin:    push    r12
  416.     push    r13
  417.     ldw    rr12,ip
  418.     next
  419.  
  420. again:    ldw    ip,rr12
  421.     next
  422.  
  423. xwhile:    pop    r13
  424.     pop    r12
  425.     next
  426.  
  427.  
  428.     .xlist
  429.  
  430. PAUSE:    push    ipl    ; push IP onto RSTACK
  431.     push    iph
  432.     ldw    rr4,SP
  433.     sub    rp1,#8    ; 16 byte context model
  434.     sub    rp0,#8
  435.     jr    nc,pause1
  436.     ld    rp0,tskptr
  437.     add    rp1,tskptr
  438. pause1:    ldw    SP,rr4
  439.     pop    iph
  440.     pop    ipl
  441.     next
  442.  
  443. ;-------------------------------------------------------------------    
  444.  
  445.     end
  446.