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