8.2. Rc/Forth

Popisuji implementace Rc/Forth ROM version 0.1.

Forth je uložen v paměti ROM od adresy 0e000h výše.

xxx

FIXME:

0000:                        org     0e000h
e000: f8 e0                  ldi     high start          ; get address of main start
e002: b3                     phi     r3                  ; and place into standard PC
e003: f8 07                  ldi     low start
e005: a3                     plo     r3
e006: d3                     sep     r3                  ; transfer control to main PC

FIXME:

e007: e2          start:     sex     r2                  ; set X to stack
e008: f8 ff                  ldi     high call           ; get address of standard call
e00a: b4                     phi     r4                  ; place into r4
e00b: f8 e0                  ldi     low call
e00d: a4                     plo     r4
e00e: f8 ff                  ldi     high ret            ; get address of standard return
e010: b5                     phi     r5
e011: f8 f1                  ldi     low ret
e013: a5                     plo     r5
e014: f8 00                  ldi     0                   ; get temporary stack
e016: b2                     phi     r2
e017: f8 ff                  ldi     0ffh          
e019: a2                     plo     r2
e01a: d4                     sep     scall               ; copy definitions to low memory
e01b: ea da                  dw      copy
e01d: f8 50                  ldi     50h
e01f: b2                     phi     r2
e020: f8 00                  ldi     0
e022: a2                     plo     r2
e023: d4                     sep     scall               ; call bios to set terminal speed
e024: ff 2d                  dw      f_setbd             ; function to set terminal
e026: f8 01                  ldi     high himem          ; get page of data segment
e028: b9                     phi     r9                  ; place into r9
e029:             
e029: f8 eb                  ldi     high hello          ; address of signon message
e02b: bf                     phi     rf                  ; place into r6
e02c: f8 c1                  ldi     low hello
e02e: af                     plo     rf
e02f: d4                     sep     scall               ; call bios to display message
e030: ff 09                  dw      f_msg               ; function to display a message

FIXME:

e032:             ; ************************************************
e032:             ; **** Determine how much memory is installed ****
e032:             ; ************************************************
e032: f8 06                  ldi     low freemem         ; free memory pointer
⋮
e077: 59                     str     r9                  ; and store

Hlavní smyčka interpretu.

e078:             ; *************************
e078:             ; *** Main program loop ***
e078:             ; *************************
e078: f8 eb       mainlp:    ldi     high prompt         ; address of prompt
e07a: bf                     phi     rf                  ; place into r6
e07b: f8 d0                  ldi     low prompt
e07d: af                     plo     rf
e07e: d4                     sep     scall               ; display prompt
e07f: ff 09                  dw      f_msg               ; function to display a message
e081: f8 00                  ldi     high buffer         ; point to input buffer
e083: bf                     phi     rf
e084: f8 00                  ldi     low buffer
e086: af                     plo     rf
e087: d4                     sep     scall               ; read a line
e088: ff 0f                  dw      f_input             ; function to read a line
e08a: f8 eb                  ldi     high crlf           ; address of CR/LF
e08c: bf                     phi     rf                  ; place into r6
e08d: f8 cd                  ldi     low crlf  
e08f: af                     plo     rf
e090: d4                     sep     scall               ; call bios
e091: ff 09                  dw      f_msg               ; function to display a message
e093: d4                     sep     scall               ; call tokenizer
e094: e1 ea                  dw      tknizer
e096:
e096: f8 06                  ldi     low freemem         ; get free memory pointer
e098: a9                     plo     r9                  ; place into data segment
e099: 49                     lda     r9                  ; get free memory pointer
e09a: bb                     phi     rb                  ; place into rF
e09b: 09                     ldn     r9
e09c: ab                     plo     rb
e09d: 1b                     inc     rb
e09e: 1b                     inc     rb
e09f: d4                     sep     scall
e0a0: e3 65                  dw      exec
e0a2:             
e0a2: 30 78                  br      mainlp              ; return to beginning of main loop

FIXME:

e365:             ; ****************************************************
e365:             ; *** Execute forth byte codes, RB points to codes ***
e365:             ; ****************************************************
e365: 0b          exec:      ldn     rb                  ; get byte from codestream
e366: 32 f2                  bz      execdn              ; jump if at end of stream
e368: ff ff                  smi     T_NUM               ; check for numbers
e36a: 32 aa                  bz      execnum             ; code is numeric
e36c: 0b                     ldn     rb                  ; recover byte
e36d: ff fe                  smi     T_ASCII             ; check for ascii data
e36f: 32 bc                  bz      execascii           ; jump if ascii
e371: f8 01                  ldi     high jump
e373: b8                     phi     r8
e374: f8 0a                  ldi     low jump
e376: a8                     plo     r8
e377: 18                     inc     r8
e378: 0b                     ldn     rb                  ; recover byte
e379: fa 7f                  ani     07fh                ; strip high bit
e37b: ff 01                  smi     1                   ; reset to origin
e37d: fe                     shl                         ; addresses are two bytes
e37e: e2                     sex     r2                  ; point X to stack
e37f: 52                     str     r2                  ; write offset for addtion
e380: f8 83                  ldi     low cmdvecs
e382: f4                     add                         ; add offset
e383: a7                     plo     r7
e384: f8 ec                  ldi     high cmdvecs        ; high address of command vectors
e386: 7c 00                  adci    0                   ; propagate carry
e388: b7                     phi     r7                  ; r[7] now points to command vector
e389: 47                     lda     r7                  ; get high byte of vector
e38a: 58                     str     r8
e38b: 18                     inc     r8
e38c: 47                     lda     r7                  ; get low byte of vector
e38d: 58                     str     r8
e38e: 1b                     inc     rb                  ; point r6 to next command
e38f: 8b                     glo     rb                  ; save RF
e390: 73                     stxd
e391: 9b                     ghi     rb
e392: 73                     stxd
e393: c0 01 0a               lbr     jump                ; jump vector

e396: e2          execret:   sex     r2                  ; be sure X poits to stack
e397: a7                     plo     r7                  ; save return code
e398: 60                     irx                         ; recover RF
e399: 42                     lda     r2
e39a: bb                     phi     rb
e39b: 02                     ldn     r2
e39c: ab                     plo     rb
e39d: 87                     glo     r7                  ; get result code
e39e: 32 65                  bz      exec                ; jump if no error
e3a0: f8 eb                  ldi     high msempty        ; get error message
e3a2: bf                     phi     rf
e3a3: f8 d4                  ldi     low msempty
e3a5: af                     plo     rf
e3a6: d4          execrmsg:  sep     scall
e3a7: ff 09                  dw      f_msg
e3a9: d5                     sep     sret                ; return to caller
e3aa:             
e3aa: 1b          execnum:   inc     rb                  ; point to number
e3ab: 9b                     ghi     rb
e3ac: b7                     phi     r7
e3ad: 8b                     glo     rb
e3ae: a7                     plo     r7
e3af: 47                     lda     r7
e3b0: bb                     phi     rb
e3b1: 47                     lda     r7
e3b2: ab                     plo     rb
e3b3: d4                     sep     scall
e3b4: e0 d8                  dw      push
e3b6: 97                     ghi     r7
e3b7: bb                     phi     rb
e3b8: 87                     glo     r7
e3b9: ab                     plo     rb
e3ba: 30 65                  br      exec                ; execute next code

e3bc: 1b          execascii: inc     rb                  ; move past ascii code
e3bd: 9b                     ghi     rb                  ; transfer name to R8
e3be: b8                     phi     r8
e3bf: 8b                     glo     rb
e3c0: a8                     plo     r8
e3c1: d4                     sep     scall               ; find entry
e3c2: e1 1c                  dw      findname
e3c4: 3b ce                  bnf     ascnoerr            ; jump if name was found
e3c6: f8 eb       ascerr:    ldi     high msgerr         ; get error message
e3c8: bf                     phi     rf
e3c9: f8 e2                  ldi     low msgerr
e3cb: af                     plo     rf
e3cc: 30 a6                  br      execrmsg
e3ce: 17          ascnoerr:  inc     r7                  ; point to type
e3cf: 17                     inc     r7
e3d0: 07                     ldn     r7                  ; get type
e3d1: ff 86                  smi     86h                 ; check for variable
e3d3: 32 e9                  bz      execvar             ; jump if so
e3d5: 07                     ldn     r7                  ; get type
e3d6: ff 87                  smi     87h                 ; check for function
e3d8: 3a c6                  bnz     ascerr              ; jump if not
e3da: e2                     sex     r2                  ; be sure X is pointing to stack
e3db: 88                     glo     r8                  ; save position
e3dc: 73                     stxd                        ; and store on stack
e3dd: 98                     ghi     r8
e3de: 73                     stxd
e3df: d4                     sep     scall               ; call exec to execute stored program
e3e0: e3 65                  dw      exec
e3e2: 60                     irx                         ; recover pointer
e3e3: 72                     ldxa
e3e4: bb                     phi     rb
e3e5: f0                     ldx
e3e6: ab                     plo     rb
e3e7: 30 65                  br      exec                ; and continue execution
e3e9: d4          execvar:   sep     scall               ; push var address to stack
e3ea: e0 d8                  dw      push
e3ec: 98                     ghi     r8                  ; transfer address back to rb
e3ed: bb                     phi     rb
e3ee: 88                     glo     r8
e3ef: ab                     plo     rb
e3f0: 30 65                  br      exec                ; execute next code
e3f2:                        
e3f2: d5          execdn:    sep     sret                ; return to caller