6839
Win10各版本号如何区分?Win10操作系统发布差不多有两年了,到目前为止,总共有四个版本,相信很多用户都不懂如何区分这几个版本,别着急,今天小编将给大家普及Win10各个版本号的相关知识,让大家轻松辨别Win10版本号!Win10各版本号如何区分?教你轻松辨别! Win10四大版本如下: 1、Win10 RTM版,即首个正式版: 开发代号:Threshold Release 1,简称th1,版本号1507(在我印象中这个版本号,并未在发布的时候使用过,是用户根据微软后面版本发布习惯给这个版本取的名字,1507表示2015年7月发布的版本,下同),操作系统内部版本号:build 10240。 2、Win10首个重大更新: 开发代号:Threshold Release 2,简称th2,版本号1511,操作系统内部版本号:build 10586。从这个版本起,每个版本都按发布年月确定一个版本号。 3、Win10一周年更新(Windows 10 Anniversary Update): 开发代号:Red Stone 1(红石1),简称rs1,版本号1607,操作系统内部版本号:build 14393。前两个版本好像都没有正式的发行名称,从这一版开始,每个版本正式发行的时候,都会取一个名字,这个版本发布时间刚好是Win10正式版发布一周年的时间,所以取名“一周年更新”。 4、Win10创意者更新(Creators Update): 开发代号:Red Stone 2(红石2),简称rs2,版本号1703,操作系统内部版本号:build 15063。从这个版本起,微软确认,每年的两次重大更新分别安排在三月和九月,所以基本可以确定,下一个版本号是1709,而版本名称已经在四月的//build 2017开发者大会上确定:秋季创意者更新(Fall Creators Update)。 总结: 以上的版本,都叫正式版。每个正式版,还会有许多小版本的安全累积补丁更新,当前的Win10最新正式版的完整版本号就是Windows 10.0.15063.413。 除了正式版,Win10还有一个内部版本计划(Insider Program),是用于测试Win10即将发布的各种新功能,新功能稳定了,就集成在正式版里面发布。这种版本一般会在正式版发布一段时间后开启测试,一般一星期推送一次更新。 既然是测试版,当然会有很多不稳定性,包括各种蓝屏、死机、卡顿,应用闪退等,所以微软是不推荐在主力机上安装测试版本的。而且安装这种版本是需要申请的,虽然门槛很低,只要一个邮箱验证登录,然后加入“Windows预览体验计划”就可以了。遇到问题,最好的办法,就是去反馈中心(Feedback)反馈,有好的创意或建议,也可以去那里提,只要你的想法好,支持你的人多,你的建议就有可能被微软采纳。 要是你在主力机主安装预览版本,碰到各种问题又骂微软,或者看到新版本推送,吐槽“又在推送了”,这样是会被大神BS的。折腾预览版,是很多人的乐趣。 PS:查看你的电脑当前运行的版本方法: 点开开始菜单,在英文状态下输入winver回车确认,就会打开“关于Windows”窗口,里面会显示各种版本信息。 关于Win10各个版本号的知识就介绍到这里了,相信大家对于Win10版本号有更深一步的了解了吧?再也不用向大神求教现在最新版本号是多少等问题了!
6530
原文转自:https://bbs.pediy.com/thread-221236.htm 作者:mrMORE Windows操作系统作为PC上最普及的操作系统,面向的用户各种各样,因此在版本升级时,对比其它操作系统,兼容性都要做得好,不需要用户费神DIY处理一些BUG。64位windows上市后大多以前32位的程序依旧正常地运行,当然这里主要指用户态程序。那64位windows是如何支持32位程序运行的呢?之前在看《windows核心编程》一书时只知道这个机制的名字叫wow64,但是具体如何实现的一无所知。为此我上网查阅资料,结果相关文章都讲得很笼统,包括Microsoft官方文档也是从很上层架构上进行了介绍,对于搞逆向的人来说,只了解架构不看代码怎么能忍,windows就在手边,何不亲自研究窥探一把庐山面目呢?说搞就搞,从代码的角度看一下这个wow64的大概。这里插一句,其实在着手了解wow64机制前,是另外一个问题先引起了我的好奇:64位CPU比32位CPU除了每个寄存器宽度多了32bit,还多了几个通用寄存器:R8, R9, R10, R11, R12, R13, R14, R15,那32位程序在win64上运行时这些新加的寄存器就没用了吗?这个问题最后也会得到解决。首先,先从宏观分析一下,32位程序的运行需要软硬件两个大方面的支持:1)硬件上,CPU的解码模式需要是32位模式。64位CPU(我只熟悉INTEL的)是通过GDT表中CS段所对应的表项中L标志位来确定当前解码模式的。这里不展开描述GDT表与CPU运行模式的关系,感兴趣的可以参看 http://www.secbox.cn/hacker/program/9875.html2)软件上,操作系统需要提供32位的用户态运行时环境(C库,WINDOWS API)对32位程序支持,其次因为win64内核是64位模式的,所以32位运行时环境在与64位内核交互时需要有状态转换。当然另外肯定还有大量其它的兼容32位软件所需要实现的功能,比如资源管理,句柄管理,结构化错误管理等等,这些属于细节就不进行研究了,我这里先看一个大体。好了,接下来针对上面的分析进行探索。关于32位运行时环境这点,可以在c:/windows/syswow64中发现许多和c:/windows/system32下同名的动态链接库,如kernel32.dll, ntdll.dll, msvcrt.dll, ws2_32.dll等,其实这些都是32位的版本。像wow64名字所传达的含义一样,syswow64文件夹下的这些库相当于在64位windows中构建了一个32位windows子系统环境,我们32位的程序能正常在win64上运行正是靠这个子环境负责与64位环境进行了交互和兼容,所以需要重点探究下这个32位子环境是如何与win64环境交互的。我这里用到的工具是 PCHunter 与调试器 MDebug,静态分析工具 IDA。了解 windows 的读者都知道 ntdll.dll 是用户态与内核态交互的桥梁,所以我选择从 ntdll.dll 入手,选择了逻辑简单的 NtAllocateVirtualMemory 函数。首先看一下原生32位操作系统里这个函数是什么样的。我手头有个 win8 32bit 版本,利用 MDebug 直接转到 NtAllocateVirtualMemory 函数查看反汇编,可以看到,在设置好调用号 0x19B 之后直接就使用 sysenter 进行了系统调用,中间没有其它操作,下面是相应的反汇编代码:NtAllocateVirtualMemory:
7778F048 mov eax, 0x19B
7778F04D call sub_7778F055(7778F055)
7778F052 ret 0x18
sub_7778F055:
7778F055 mov edx, esp
7778F057 sysenter
7778F059 ret看完原生32位操作系统里的样子,win64 中运行一个 32 位程序时它的进程空间里的NtAllocateVirtualMemory 是一番什么情景呢?我手头有 win7 64bit 版,运行的一个32bit程序进行调试,可以看到 NtAllocateVirtualMemory 的形式如下:NtAllocateVirtualMemory:
77C8FAD0 mov eax,0x15
77C8FAD5 xor ecx,ecx
77C8FAD7 lea edx,[esp+0x4]
77C8FADB call dword ptr fs:[000000C0]
77C8FAE2 add esp,4
77C8FAE5 ret 0x18OK,区别很明显,wow64中的 ntdll.dll 与原生32位 windows 中的 ntdll.dll 有了变动,它不再是与内核交互的最后一个用户态模块,而是call 进了fs:[C0]处的函数,隐约感觉这里就是打开wow64秘密的入口。fs:[C0] 是什么呢?Windows操作系统中,fs寄存器用于记录线程环境块TEB,根据TEB结构体定义可以看出0xC0偏移处的定义为:PVOID WOW32Reserved; // 0C0其实在wow64之前还有wow32机制,用于兼容16位程序在32位windows上运行,与wow64异曲同工。所以 windows 系统在 wow64 中直接也拿这个保留位置用于进行32位64位环境切换的跳板。单步跟进,发现fs:[C0]处只有一行代码:752B2320 jmp 0033:752B271E这里是一个长跳转,目的地址是内存752B271E处,但是MDebug调试器显示752B271E处于未知模块。这时需要借助PCHunter,通过PcHunter发现该地址其实位于一个叫wow64cpu.dll的模块中,值得注意的一点是,该模块来自 system32 而非syswow64 目录,是64位的文件模块,也就是说,wow64下32位程序的进程空间内同时加载了32位与64位的可执行文件模块!在这个32位程序的进程空间里一共有4个来自SYSTEM32 目录64位的“客人”:终于,这里有了真正的64位 ntdll.dll 的出现。所以很容易可以推断,wow64.dll, wow64win.dll, wow64cpu.dll 组成了环境转换模块,而最终依然是ntdll.dll 负责与内核交互,wow64中这4个模块在默默地在后台支持着32位程序的运行。上面说到这里经历了一个长跳转,段寄存器由0x23变换为0x33,在win64中,0x23和0x33所对应的GDT表项中CPU的模式分别为32位与64位。自此,CPU解码模式由32位切换为64位。当然,故事还没结束。不过由于调试器是32位,无法准确捕获接下来发生的事情,单步跟进也没用了,我们转为使用IDA静态分析。找到 752B271E 所对应的 wow64cpu.dll 中的位置:00000000752B271E mov r8d,[esp] //取出返回地址
00000000752B2723 mov [r13+0xBC],r8d //保存返回地址
00000000752B272A mov [r13+0xC8],esp //保存32位环境堆栈指针
00000000752B2731 mov rsp,[r12+0x1480] //切换至64位环境堆栈
00000000752B2739 and qword ptr [r12+0x1480],0x0
00000000752B2742 mov r11d,edx
00000000752B2745 jmp qword ptr [r15+rcx*8]第一句读取[esp]的值其实是把返回地址取出,接着保存到了r13所指向的地方,同时还保存了esp,然后重新赋值了rsp。看了这一小段,我们基本可以猜测到,在wow64中那个幕后的64位环境里其实是有自己的堆栈和执行上下文的,在CPU由32位切换到64位后,堆栈也相应切换。好了,下面要搞最后一句跳向了哪里,也就是[r15+rcx*8]的值,我们上面考察的 NtAllocateVirtualMemory 有 xor ecx, ecx 的操作,所以到这里时rcx = 0,所以就我们考察的例子而言,最后就是跳转到了[r15]。那,r15的值是多少?这是有点棘手的问题。Wow64中32位程序只能由32位调试器调试,但是32位调试器下又无法获得64位模式下才可见的r15的值,怎么办?我这里使用shellcode的方式,利用32位MDebug调试shellcode的功能调试精心准备的一段shellcode,这段shellcode的作用独特而简单:让CPU切换到64位模式下“潇洒走一回”,将R8 ~R15的值记录到堆栈中,接着切换回32位模式。shellcode的二进制为:\x6A\x33\xE8\x00\x00\x00\x00\x83\x04\x24\x05\xCB\x48\xB8\x88\x77\x66\x55\x44\x33\x22\x11\x50\x41\x50\x41\x51\x41\x52\x41\x53\x41\x54\x41\x55\x41\x56\x41\x57\x50\xE8\x00\x00\x00\x00\xC7\x44\x24\x04\x23\x00\x00\x00\x83\x04\x24\x0D\xCB它的反汇编如下:/*开始时CPU处于32位模式*/
Push 0x33 // cs = 0x33
Call L1
L1:
add [esp], 5
retf // far ret,切换CPU状态
/*此时CPU处于64位模式*/
mov rax, 1122334455667788h //将r8~r15用特殊值与周边数据隔开,方便查看
push rax
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push rax
Call L2:
L2:
mov [esp + 4], 0x23 // cs = 0x23
add [esp], 0xd
retf虽然32位调试器无法对64位代码运行时下断,但是可以在切换回32位模式后的地方下断点。所以在这段代码后下一个断,运行代码。执行完毕后,查看一下堆栈上的收获: 地址 内容
0018FEA0 1122334455667788
0018FEA8 00000000752B2450 r15
0018FEB0 000000000008EC80 r14
0018FEB8 000000000008FD20 r13
0018FEC0 000000007EFDB000 r12
0018FEC8 0000000000000246 r11
0018FED0 0000000000000000 r10
0018FED8 0000000077C8FAFA r9
0018FEE0 000000000000002B r8
0018FEE8 1122334455667788 Bingo!我们成功获得到了32位程序运行环境下R8~R15的值,根据R15的值定位出它同样位于wow64cpu.dll文件模块内,根据R15的值 找到wow64cpu.dll中相应的位置,发现是指向了一堆函数指针:.text:0000000078B62450 dq offset TurboDispatchJumpAddressEnd
.text:0000000078B62458 dq offset sub_78B62DBA
.text:0000000078B62460 dq offset sub_78B62BCE
.text:0000000078B62468 dq offset sub_78B62D6A
//后面还有很多函数指针,此处省略其实在第一次打开wow64cpu.dll寻找752B271E位置时,就可以看到它附近有一个名为CpuSimulate的函数,里面有这样的操作:.text:0000000078B625F9 mov r12, gs:30h
.text:0000000078B62602 lea r15, off_78B62450可以看到r15是指向了偏移78B62450处,对应动态加载后就是752B2450。所以这也印证了我们的实验结果。另外还可以看到的一点是r12指向了64位下的TEB(64位下gs段寄存器用于记录TEB结构)。所以很显然,[r15]是指向了TurboDispatchJumpAddressEnd处,就是上文jmp qword ptr [r15+rcx*8]所要跳转到的地方(因为ecx = 0),看一下它的代码:TurboDispatchJumpAddressEnd:
.text:0000000078B62749 mov [r13+0A4h], esi
.text:0000000078B62750 mov [r13+0A0h], edi
.text:0000000078B62757 mov [r13+0A8h], ebx
.text:0000000078B6275E mov [r13+0B8h], ebp //保存32位环境下的寄存器
.text:0000000078B62765 pushfq
.text:0000000078B62766 pop rbx
.text:0000000078B62767 mov [r13+0C4h], ebx //保存32位环境的eflags
.text:0000000078B6276E mov ecx, eax //调用号
.text:0000000078B62770 call cs:Wow64SystemServiceEx //继续完成未尽竟的事业
.text:0000000078B62776 mov [r13+0B4h], eax
.text:0000000078B6277D jmp loc_78B62611上面的代码最后跳转到78B62611,loc_78B62611的代码如下:text:0000000078B62611 loc_78B62611:
.text:0000000078B62611 and dword ptr [r13+2D0h], 1
.text:0000000078B62619 jz loc_78B626CE
.text:0000000078B6261F movaps xmm0, xmmword ptr [r13+170h]
.text:0000000078B62627 movaps xmm1, xmmword ptr [r13+180h]
.text:0000000078B6262F movaps xmm2, xmmword ptr [r13+190h]
.text:0000000078B62637 movaps xmm3, xmmword ptr [r13+1A0h]
.text:0000000078B6263F movaps xmm4, xmmword ptr [r13+1B0h]
.text:0000000078B62647 movaps xmm5, xmmword ptr [r13+1C0h]
.text:0000000078B6264F mov ecx, [r13+0B0h]
.text:0000000078B62656 mov edx, [r13+0ACh]
.text:0000000078B6265D and dword ptr [r13+2D0h], 0FFFFFFFEh
.text:0000000078B62665 mov edi, [r13+0A0h]
.text:0000000078B6266C mov esi, [r13+0A4h]
.text:0000000078B62673 mov ebx, [r13+0A8h]
.text:0000000078B6267A mov ebp, [r13+0B8h]
.text:0000000078B62681 mov eax, [r13+0B4h] //恢复32位环境寄存器
.text:0000000078B62688 mov [r12+1480h], rsp //保存64位环境堆栈指针
.text:0000000078B62690 mov [rsp+0B8h+var_B0], 23h
.text:0000000078B62697 mov [rsp+0B8h+var_98], 2Bh
.text:0000000078B6269E mov r8d, [r13+0C4h] //之前保存的32位环境eflags
.text:0000000078B626A5 and dword ptr [r13+0C4h], 0FFFFFEFFh
.text:0000000078B626B0 mov [rsp+0B8h+var_A8], r8d
.text:0000000078B626B5 mov r8d, [r13+0C8h]
.text:0000000078B626BC mov [rsp+0B8h+var_A0], r8
.text:0000000078B626C1 mov r8d, [r13+0BCh]
.text:0000000078B626C8 mov [rsp+0B8h+var_B8], r8
.text:0000000078B626CC iretq //排好堆栈,返回至32位模式返回地址处可以看到,在 TurboDispatchJumpAddressEnd 代码片段中,调用了一个外部函Wow64SystemServiceEx,由这个函数再继续把下面的事情做完,最终调用64位的 ntdll.dll的 NtAllocateVirtualMemory 来完成整个操作。TurboDispatchJumpAddressEnd 最后跳转至78B62611,将CPU主要寄存器值恢复至之前保存好的32位环境中的值,同时在堆栈中排布好返回地址,cs段寄存器值,eflag值,执行iretq,返回至32位环境中,在我们的例子中,即返回到 NtAllocateVirtualMemory 中 call dword ptr fs:[C0] 的下一句,看起来像真的执行了一个普通函数一样。上面讲到跳转的函数指针表是根据r15+rcx*8来得到的,在32位进程空间的那个ntdll.dll里面 call dword ptr fs:[C0] 前都有对ecx的赋值,我们可以推测在wow64中,系统调用被分成多类,类别号存在于rcx中,根据rcx的值来进行不同类别的模拟转换。Wow64SystemServiceEx 做的事情就暂时不详细研究了,感兴趣的可以细细钻研。对这次简单的wow64之旅做个小总结:1) windows/syswow64目录下的大量DLL库与SYSTEM32目录下的wow64.dll, wow64cpu.dll, wow64win.dll, ntdll.dll 支撑着wow64机制。2) Wow64下32位进程中实际有32位和64位两个逻辑子空间,每个子空间都 有各自的数据结构、堆栈,64位子空间负责与操作系统内核交互:32位用户态模式 <---------> 64位用户态模式 <------------------> 64位内核3)Wow64模式下,那些不可见的寄存器并不都是闲置不用的,在切换到64位环境后全部启用,和正常64位程序无差别。且经过分析可以知道有确切作用的寄存器有:R12: 指向64位环境的TEB结构体 R13:指向保存32位环境CPU的状态的位置R15: 指向跳转函数指针列表的起始上面是针对win7下做的一个wow64机制小探索,我也简单看了下在win8和win10下的wow64过程,在反汇编代码上有些小不同,但是逻辑原理是完全相同的,感兴趣的读者可以搞一把。
4966
原文转载自:http://mp.weixin.qq.com/s/_-QDjvNv44Esn9O0EChh4A“不忘初心,方得始终。”只有不忘记自己最初的想法,才能有始有终地去完成自己的梦想。“初心”是什么?是孔子“居之不倦,行之以忠”的为政之道;包拯“清心为治本,直道是身谋”的为官箴言;是毛泽东“埋骨何须桑梓地,人生无处不青山”的豪情壮志;是周恩来“为中华之崛起而读书”的宏大理想。不忘初心,方得始终。只有走过弯路,才更确信当初最想要的是什么。真正重要的不是生命里的岁月,而是岁月中的生活。流光容易把人抛,红了樱桃,绿了芭蕉。曾经莫失莫忘,后来梦里花落。纳兰性德说,“人生若只如初见”。在这个时代,初心常常被我们遗忘,“我们已经走得太远,以至于忘记了为什么出发”。因为忘记了初心,我们已经不知道为什么来,要到哪里去。因为忘记了初心,我们走得十分茫然,多了许多柴米油盐的奔波,少了许多仰望星空的浪漫。因为忘记了初心,时光荏苒之后,我们会经常听到人们的忏悔:假如当初我不随意放弃,要是我愿意刻苦,要是我有恒心和毅力,一定不会是眼前的样子。席慕蓉说:我一直相信,生命的本相,不在表层,而是在极深极深的内里。这里的“内里”即为“初心”,它不常显露,很难用语言文字去清楚形容,只能偶尔透过直觉去感知其存在,但在遇到选择之时,在不断地衡量、判断与取舍之时,往往能感知其存在。林清玄说:回到最单纯的初心,在最空的地方安坐,让世界的吵闹去喧嚣它们自己吧!让湖光山色去清秀它们自己吧!让人群从远处走开或者自身边擦过吧!我们只愿心怀清欢,以清净心看世界,以欢喜心过生活,以平常心生情味,以柔软心除挂碍。白岩松说:在墨西哥,有一个离我们很远却又很近的寓言。 一群人急匆匆地赶路,突然,一个人停了下来。旁边的人很奇怪:为什么不走了? 停下的人一笑:走得太快,灵魂落在了后面,我要等等它。我们都走得太快。然而,谁又打算停下来等一等呢?如果走得太远,会不会忘了当初为什么出发?人生只有一次,生命无法重来,要记得自己的初心。经常回头望一下自己的来路,回忆起当初为什么启程。经常纯净自己的内心,给自己一双澄澈的眼睛。不忘初心,才会找对人生的方向,才会坚定我们的追求,抵达自己的初衷。一窗暖阳,一念心安,初心仍在,岁月无恙。闲看花开,静待花落,冷暖自知,干净如始。我希望,今后能以一朵花的姿态行走世间,穿越季节的轮回,在无声中不颓废,不失色,花开成景,花落成诗。回忆中,总有一些瞬间,能温暖整个远去的曾经。世界上唯一的你,就算没有人懂得欣赏,也要好好爱自己。时间很短,天涯很远。今后的一山一水,一朝一夕,安静的去走完。前尘过往终是浮云,最应该珍惜的便是当下。任岁月流逝,你我初心终不改。淡然安逸,心静如水,肆意而恬淡,这才应该是你的生活。-END-
6035
原文地址:http://k.sina.cn/article_1708729084_65d922fc001002e56.html?wm=3049_0016&from=qudao 2017年9月10日-13日,由工业和信息化部、科技部和江苏省人民政府主办的世界物联网博览会在无锡举行。博览会开幕首日的高峰论坛上,来自政府、企业的互联网、物联网专家学者围绕物联网主题,从不同角度发表富有创见的精彩演讲,分享对各自领域物联网发展的独到思考,带来一场智慧的碰撞和思想的盛宴。压轴演讲嘉宾阿里巴巴集团董事局主席马云先生的演讲更是颇具深意。
两天前,恰逢阿里巴巴集团成立18周年庆典。18年前,马云创办阿里巴巴,“今天的阿里巴巴不是今天做成的,是18年以前的决定做成的。而18年以后的你、20年以后的你,不是20年以后决定的,而是今天的思考、今天的决定。”马云以惯有的演讲风格挥洒他对物联网和成功学的思考。2009年开始,江苏就进行了物联网的探索,那时候国家,将今天的物联网叫做国家传感网。也是2009年,阿里巴巴启动了阿里云计算,那时候谁也说不出未来云计算到底是怎么一个样子,但是我们相信这是一个未来、这是一个趋势。双方都坚持了八年时间,才有了今天。
马云先生将江苏省对物联网的探索与阿里巴巴的探索进行了分析:江苏省开始探索的时候,我相信大家只是觉得这是一个概念,阿里巴巴在探索云计算的时候,也认为是一个概念,今天的概念越来越多,包括云计算、大数据、智能物流、IOT在内各种各样的说法,其实说明一个问题,人类正在往一个共同的方向去走。就像上一个世纪,有的人讲汽车很重要、有的人说造路很重要、有的人说石油很重要,其实大家都在做一个方向,这就是一个能源时代的到来,而今天的人类将真正开始进入到数据时代。在马云的思想宇宙里,数据化技术足以和社会化生产比肩:人类未来的大数据发展,离不开三个主要的要素,就是互联网、大计算以及云数据。数据将成为最重要的生产资料,大数据涵盖着两个关键,“大”不是“多”的意思,“大”是大计算的意思,大计算加云数据,这才是我们所认为的大数据。首先数据将成为最重要的生产资料,如果说第一次技术革命,煤是主要的生产资料、煤是主要的动能,第二次技术革命,是石油、电,这次技术革命,以创新驱动,数据将成为最重要的生产资料第三次技术革命将以创新驱动,数据将成为最重要的生产资料。
互联网本身是一种生产关系,互联网不是互联网公司的互联网,互联网是全社会的互联网。云计算将成为一种强大的生产力。 的确,当技术的发展不断向外部发展的时候,数据化趋势正在走向我们的内心:过去的两百年,由于科技的发展,我们对外部的世界越了解越多,我们走向外太空,探索月亮、探索火星,不断在向外探索,但是人类对自我的了解越来越少,未来的一两百年,我们在发掘人类的内心世界,这在生命科学方面将会有重大的突破。人活到120岁、150岁,并不是笑谈和奢想,因为人将了解自己越来越多。
我们对于未来的未知远远大于已知,就像阿里巴巴不是今天做成的,是18年以前我们相信有这一天才会做成的。我们今天同样相信未来的世界会是这个样子,并且为之去努力。 马云相信,今天能够定义清楚的东西都不是未来,今天我们怎么想象未来,在他认为都是幼稚的,尽管18年以前,我们知道互联网会发展,知道电子商务会发展,但是我们没有想象到电子商务、互联网18年以后会发展成这个样子。人类一百年以前发现电的时候,认为电就是用于电灯泡的,并没有想到今天还有电饭煲、空调机,今天我们对于数据的理解,所谓的数据垄断,跟二十年以后的数据相比,跟万物相连以后的数据相比,比不上沧海一粟。所以我们今天要思考的是如何面对未来,我们要铺设一个方向,如何坚持,并且不断的去完善。今天的思想碰撞极具意义,甚至是里程碑式的。 时代的变迁在18年前被他和他的团队亲手开拓,18年后的未来,也正在这位传奇人物的预言中慢慢走来:身处IT时代,人类已经从IT走向DT,IT是Information Technology,DT是Data technology,这不是字的区别,也不是技术的区别,而是思想观念的区别,IT是让自己做得越来越强,而DT必须学会共享,必须学会普惠,必须让别人强大起来,你才会强大起来。而整个世界的趋势就走向了普惠、共享和可持续。
5638
原文地址:https://jingyan.baidu.com/article/73c3ce28c97bb6e50243d96e.html文章所需使用软件:Mkvmerge GUI FLVExtract
第一步:提取FLV文件视频流、音频流
打开FLVExtract,出现下面的窗口:
然后将需要处理的FLV文件拖入FLVExtract窗口内,视文件大小等待一会儿,出现下如下窗口:
单击OK,关闭软件,然后你会发现FLV视频文件目录下生成了视频流文件(一般为.264文件、AVI文件等),音频流文件(一般为AAC文件、MP3文件等),以及脚本流文件(TXT文件)这三个文件:
到此,提取FLV文件视频流、音频流这一步完成。
第二步:合并视频流、音频流文件,封装成MKV格式
打开MKVMerge GUI,将刚刚生成的视频流以及音频流文件添加进去(脚本流文件并非必要,一般可以删除):
根据第一步中得到的一些信息设置格式细节选项:
开始混流(时间一般来说在2分钟以内):
混流完成,耗时仅2秒,单击确定:
关闭软件,发现FLV文件目录下已经生成了同名的MKV格式文件(画质及清晰度没有改变,但却缩小了源FLV文件的大小哦):
注意事项
对于F4V格式视频文件,HLV格式视频文件等非FLV格式视频文件的处理,大家可以直接重命名、修改扩展名为FLV(不必担心损坏视频文件)。
6069
名称:FLV文件内部音频提取 ( FLVExtract )
大小:0.5 MB
语言:中文
授权:免费软件
更新:2017-09-03
官网:未知
平台:Windows介绍: FLV Extract是一款可快速从Flv格式文件中提取音频和视频的小工具,和其它软件不同的是,FLV Extract软件在提取的时候不需要对文件进行解码和编码,瞬间就能将视频和音频文件提取出来,并且可以保留原始文件的音质效果,FLV Extract还有如下优点: # 文件小巧(不到50K),无需安装,且是免费开源软件; # 简洁的界面以及易操作性(只需将flv文件拖拽到软件主界面即可); # 音频直接提取为mp3格式,视频直接提取为avi格式(支持H.263/FLV1 和 VP6/VP6F) 注意:软件运行环境需要Microsoft .Net 2.0组件,Win7及更老系统需要自行安装运行截图:下载地址:点击下载FLV Extract
5853
原文地址:http://database.51cto.com/art/201708/548354.htm作者:古的白人生大起大落落落落落落,实在是太刺激了,下面这真是一个悲伤的故事。那年公司 ERP 系统刚进行升级。因为公司陆续上了 MES 和 PDM 系统。为了加快整个公司信息化平台的统一,请了个第三方公司来做中间接口。然后故事开始了。某一个晚上,第三方人员问我要 ERP 的 SA 密码。我很警惕:“你要干嘛?”“我测试一下中间表。”“有没有写表的操作?”“没有,只有读表的操作。”于是我放心的给了 SA 密码。给了 VPN 权限通道。放她进来了。十分钟后…..她带着哭腔打电话来(是的,对方做测试的是个 93 年的萌妹子。)“吴哥哥,服务器中毒了。。。。”我当时还在逛果壳呢,一听她说我服务器中毒了,我表示无比淡定。还以大哥的经验教训了一顿她。“叫你不要往我服务器传插件嘛,这次帮你解决一下,下次不准了哟。”我认为是小 case 呢,不就中毒了嘛,系统往回滚一天就好了。然后悲剧的事情就出现了,远程进不去,于是我就去机房本地登录,居然也进不去。我不死心,强制重启,居然还是进不去。我的服务器系统就这样崩了。。。好在那几天在做开发,系统没有启用,于是我和我的老板汇报了这个情况:“老大,我们服务器系统崩了。”“哦,那就搞好它让它别崩。” 果然是霸道总裁啊。当时数据和应用服务器我都是分开跑的,所以应用服务器奔溃了,我觉得也没多大事,就重新做系统吧。于是我重新做了个系统,然后喊萌妹子上来搭平台。“小刘啊,你可害惨我了,一个下午给你重做服务器系统了,我基础环境都配置好了,你上来搭平台吧。”萌妹子那是无比的歉意啊,又是答应请我吃饭又是答应请我看电影的。我都想系统再崩溃一次了。按理说这样应该是没问题了,就在我走出机房,在外面抽了根烟,45 度仰望了一下天空,联想了一下和萌妹子点个 9 分熟的牛排,在喝一口二锅头这样浪漫的晚餐的时候。电话来了。来电话的是萌妹子的老板。“小吴,我想找一下 information.db 和 mfmedia.db 这两个总表没找到,你给我找一下。”我都蒙了,从来没人问过我这样的问题,难道她老板不是 IT 行业的。“数据库文件都在目录树里啊,自己去找啊。”“没有。”于是我登上服务器一看,我傻了。所有的表都空了,所有的表都静静的躺在那,但是里面都空了。。。不可能啊,我数据库是放在另外一台服务器上的,怎么可能会没有了。于是我问萌妹子:“XXX,你到底做了什么操作啊,为毛我数据库都没了。”萌妹子说:“我啥也没干啊,只是按照步骤一路点 YES。”我才想起来,在第一次配置基础环境的时候,建账套会提示是否初始环境,如果点是了,数据库就会被初始化,然后这位萌妹子傻傻的点了是。“你知道不知道你干了什么,公司 06 年到现在所有的数据,财务的,供应链的,进销存的全部都在这台服务器里,200 多个 G 数据,因为你一个是,全没了。”萌妹子也吓蒙了,话都说不出来了。没办法,我再给我老板打电话。“老板,有个好消息,有个坏消息。”“直接说坏的。” 我就喜欢我们老板这么直接。“恩。。恩。。那个。。就是那个。ERP 的数据没了。”“哦,那就找回来。” 老板还是那么的霸气。我特么都要爱上他了。“老板,我想你没明白这个的严重性。ERP 数据没了,从 06 年开始的都没了,这意味着就算找回来,整理所有的表,排错也需要 3 天左右时间,到时候所有的生产都要暂时停止。如果找不回来,我们可能就要倒闭了。”我忽然有种掌握天下苍生的感觉。。。对面沉默了 5 秒后,爆吼了一句:“吴 XX,你给我滚到我办公室来!!”中间和老板手握手谈心,被老板亲切慰问的细节跳过不表。当时公司高层对数据安全还没有那么重视,之前预算做的项目,我已经做了备份的计划书,一直没被审批下来,现在估计悔得肠子都清了。于是我开始漫长的数据恢复之旅。我之前已经做了个本地备份的计划,每天晚上会备份一次。我把希望都放在了它身上。等我把备份的数据库附件上去,发现时间居然都是两个星期之前的。而且还有一些新表都没有,我联系对方,对方告知研发人员两个星期前做测试的时候把备份计划关了。。。我心里万头草泥马奔腾而过。最后没有办法,把老服务器又翻了出来,翻出之前的老数据,开始转换。期间老板给我短信:“数据恢复进行的怎么样了呢。”“报告,正在稳步进行中,按照目前的状况,可恢复的可能性超过 90%。” 别问我 90% 怎么算出来的,我就是哄他才这样说的。“唉,真是心急呀,睡都睡不着。小吴呀,当初要是听你的,上了备份该多好呀。” 现在知道后悔了,哼哼。“老大别担心,我会搞定的。” 是的,作为一位负责的员工,我就是这么让老大心安。“恩,那就交给你了哦,熬夜少抽点烟哦。” 哎呀,瞬间觉得我老大萌萌哒有没有。这里花了我一个晚上加一个白天。数据转换好了,还有一些时间差的数据没法找到。于是通知各个部门,找单据,开始往里面补单子,一条一条的按照业务流程补进去。为了协同更方便,在会议室加设了几十台电脑集体办公。。。在大家一片怨声载道中,三天时间,终于把数据恢复了过来。三天内我没离开机房超过 10 米,吃喝拉撒都在机房,不对,拉撒不在。这件事情造成的后果:1. 大部分员工放假三天,我加班三天三夜。2. 本来很爱我的大部分员工因为单据事件,集体转为黑我恨我了。3. 公司立马批了我的计划,冷备,热备,异地容灾,全部上全了。4.我挥刀自宫,自己罚了自己,扣除了自己一个月工资。5.老板到现在还是在怀疑请的那家公司已经被我们竞争对手收买,是故意来破坏我们的。6.萌妹子拉黑了我。
4566
原文转自:http://bbs.51cto.com/thread-1082542-1.html作者:imcxz时间快到了下午五点半,我盖好笔帽,浏览了一遍当天的笔记,打卡锁电脑,准备下班……来到公司已有将近三年的时间,当时我是处于公司IT人手不够情况下应聘进来的,第一年公司着手搬家,领导带着我参与了新机房建设、新办公区网络规划、机房搬迁等相关工作,我因此学到了很多知识。第一年下半部和第二年,我参与了多项完善、测试及上线工作,例如下一代防火墙、无线网络、oracle存储、ESXI升级、专线部署、备份、软硬件资产管理、相关文档的起草和撰写等。那是充满忙碌和激情的两年时间,我不断学习、进步、丰富自我的专业知识,虽然经常加班,虽然很累,但是乐在其中不知疲倦。经过了将近两年时间的忙碌和完善,公司的IT系统趋于巩固。由于各方面的原因吧,我们进入了一个平缓期,项目没有了,测试也没有了,每日局限于查看日志,小修小改,就像从顶楼一下滑落到了地下室,及其不适应,浑身发痒的感觉也越来越强烈。我不可避免的也开始了迷茫,一下不知道自己该做些什么,每日重复的工作让我毫无乐趣,虽然都是一些机械化的操作,但是脑子却变得越来越迟钝,越来于迷糊了。这样的情况持续了将近半年的时间,大家逐渐趋向于安逸的节奏,上班无非浏览新闻,广播网购打折信息,QQ打屁YY之类的无聊之事,逐渐的开始有了员工的离职,而让我顿悟的是几个老员工的离职,给了我警示——不能再这样下去了。我开始反省,才发现自己掌握的知识实在是少的可怜,涉及公司技术的方面,例如AD、exchange、lync、邮件网关、虚拟化、存储、防火墙等只是有了一个概面的了解,尤其对于自己主要负责的网络方面,基础理论的掌握实在是差的厉害,总结出来就是——我知道要这么做,但是不知道为什么要这么做。这让我失落、但立即想到的是行动。我开始重新复习原来了解的知识方面,从最基础的开始。按照自己的习惯,我延续了在学校的方法,一遍复习一遍做笔记,到目前为止,我重新学习了一遍lync、exchange、ESXI基础架构、CCNA、CCNP网络。重新学习的过程是枯燥无味的,但效果就是你能和现有的生产环境结合起来,触通旁类!例如acl方面,除了常规的配置,你可以了解基于时间的acl、自反acl等等。在学习的过程中,你会有经常性的顿悟,那样的感觉不可言表。我的一个同学嘲笑我沉迷于无前途的技术,我无法反驳,我只想做自己喜欢的事情,或者我可以跳槽、转行,而且有可能在其他领域能够赚取更多的金钱,但我觉得那还没有到时候,我从最初连LYNC都没听过的小菜鸟,到现在能够负责公司网络部分的转变;从最初的杂乱不精自以为是,到现在的系统分析冷静判断;这都是端正心态、不断积累的结果。(这只是个人态度,大家看看即可,不要因此放弃难得的机遇)我想起曾读过多遍的一部小说里面的话:“生命的精彩、幸福的喜悦不在于人努力后得到的结果,而在于创造结果的过程!”不要看不上Helpdesk,照样可以做的精彩;不要觉得微软傻瓜化,要精通非常困难;不要以为虚拟化缥缈,基础掌握并不复杂;不要把程序猿屌丝化,搞个后门让你瞪眼;不要把攻城狮当民工,键盘一敲让你网络全挂。学到的看到的越多,才发现自己知识的匮乏,处于一个安逸的时期,暂时的迷茫是正常的,最主要的还是要及时发现自己的问题,不断的去研究、学习、请教,丰富自我。因此我认为——暂时的安逸,是为将来的激情做准备!——谨以此文献给所有感觉自己安逸的午饭们!————2013年11月12日晚
5240
原文地址:http://weibo.com/ttarticle/p/show?id=2309351002704146441940550858&u=1668632407&m=4146441712461037&cu=1668632407写在前面前两天和几位技术大牛聊天,大家突然发现那些身边的优秀的技术人中,有很多人都拥有相同的路径和很多共同点。简单的说,技术大牛虽然凤毛麟角,但其实成为技术大牛也没有那么困难,就是“有技巧无捷径”。“有技巧”是说,任何一个领域的专家,只要精通该领域的已有知识就可以,只要你的学习能力够强、能够掌握一些经验技巧就一定能够办得到,不像很多岗位对于“创新”的要求,需要用已有的知识创造出未知的产品。“无捷径”是说水到渠成,你把该做的事情一件一件琢磨好,在每一件事情上多下点功夫,自然而然就会有“渠”。除了技术类岗位,很多岗位的要求也都一样,胜任力或者发展轨迹很清晰,看似不难,难得是有人可以沉得下心来细细打磨。就来说说技术大牛们通常不同阶段的注意力都在哪,也可以说是需要你沉下心来好好打磨的四个层次——第一个层次,专业领域内的技术精通。要作为一名技术领域的强人,必须要确保在某个技术方向上非常精通,技术的根基要扎得非常深,稳扎稳打,这是你的技术招牌。前两天朋友圈有人问:“面试时候是否会问设计模式相关的问题。”很多大牛表示很少问道,因为越是优秀的技术人员,注意力越是在一线技术上,越是关注在表面花哨的东西,越写不出牛逼的代码。所以第一个层次,需要沉得下心,深钻技术,细细打磨。第二个层次,有一定的技术广度。技术的深度和广度本来就是一个相辅相成的协同,有时候其实没有办法分出个先后。你会发现,很多技术大牛非常非常的博学,他们似乎都精力无限、兴趣广泛?没错,广度这个事情指的就是信息量,而信息量的获取往往跟精力和兴趣相关。 很多人会询问技术的深度和广度那个更重要,我觉得“吃透一样才是立身之本”,所以广度应该有,但是更多的时候“广度”要辅助“深度”。即时很多事情你并没有做过,但一定要清楚个二三,需要的时候可以立即钻进去。所以第二个层次,需要的是走出去的心境。第三个层次,潜入到行业中了解业务和流程。做得越多,你越会发现没有技术独立存在的场景,技术的存在是为了更好的服务于应用场景,不潜入到一个行业当中,不知晓行业的应用环境、组织流程、商业价值,就难以做出和业务无痕交融的产品。技术是把商业需求转换成产品的一个关键角色,因此第三个层次,需要的是了解技术以外的东西。第四个层次,了解社会心理学。做得更多,你会发现,你会从对技术的研究,变为对行业的研究,再变为对人性的研究。产品最终是为了满足人的需要才有价值,而产品研发本身也需要多人协作。社会心理学主要是研究人际关系。当然了,我觉得这个还是非常难的,一般做到二三层次就已经可以是技术大牛了。对CEO的要求可以这么苛刻。
6669
比尔·盖茨31岁,就成为世界首富。很多人好奇,作为世界第一大PC系统的创始人,抛弃世界首富的头衔,单单从程序员角度来讨论,比尔盖茨的代码水平如何?其实,比尔·盖茨对写代码有一种狂热的喜好。上高中的时候,为了获得源代码,比尔·盖茨曾经去翻垃圾桶。据了解,在1978年的Microsoft BASIC源代码6502中,比尔·盖茨实现了FOR和GOSUB的所有BASIC语句,函数,运算符,表达式评估,堆栈管理,内存管理器,数组和字符串库。昨日,编程网站w3cschool报道,在未经微软或比尔盖茨同意的情况下,某人公开了1978年的Microsoft BASIC for 6502源代码,以及原始评论、文档和彩蛋,这是目前公开的比尔·盖茨写的最古老程序。除了比尔盖茨外,很多互联网大佬都是程序员出身,比如马化腾、比如雷军等人。TITLE BASIC M6502 8K VER 1.1 BY MICRO-SOFT
SEARCH M6502
SALL
RADIX 10 ;THROUGHOUT ALL BUT MATH-PAK.
$Z:: ;STARTING POINT FOR M6502 SIMULATOR
ORG 0 ;START OFF AT LOCATION ZERO.
SUBTTL SWITCHES,MACROS.
REALIO=4 ;5=STM
;4=APPLE.
;3=COMMODORE.
;2=OSI
;1=MOS TECH,KIM
;0=PDP-10 SIMULATING 6502
INTPRC==1 ;INTEGER ARRAYS.
ADDPRC==1 ;FOR ADDITIONAL PRECISION.
LNGERR==0 ;LONG ERROR MESSAGES.
TIME== 0 ;CAPABILITY TO SET AND READ A CLK.
EXTIO== 0 ;EXTERNAL I/O.
DISKO== 0 ;SAVE AND LOAD COMMANDS
NULCMD==1 ;FOR THE "NULL" COMMAND
GETCMD==1
RORSW==1
ROMSW==1 ;TELLS IF THIS IS ON ROM.
CLMWID==14
LONGI==1 ;LONG INITIALIZATION SWITCH.
STKEND=511
BUFPAG==0
LINLEN==72 ;TERMINAL LINE LENGTH.
BUFLEN==72 ;INPUT BUFFER SIZE.
ROMLOC= ^O20000 ;ADDRESS OF START OF PURE SEGMENT.
KIMROM=1
IFE ROMSW,<KIMROM==0>
IFN REALIO-1,<KIMROM==0>
IFN ROMSW,<
RAMLOC= ^O40000 ;USED ONLY IF ROMSW=1
IFE REALIO,<ROMLOC= ^O20000 ;START AT 8K.
RAMLOC=^O1400>>
IFE REALIO-3,<
DISKO==1
RAMLOC==^O2000
ROMLOC=^O140000
NULCMD==0
GETCMD==1
linlen==40
BUFLEN==81
CQOPEN=^O177700
CQCLOS=^O177703
CQOIN= ^O177706 ;OPEN CHANNEL FOR INPUT
CQOOUT=^O177711 ;FILL FOR COMMO.
CQCCHN=^O177714
CQINCH=^O177717 ;INCHR'S CALL TO GET A CHARACTER
OUTCH= ^O177722
CQLOAD=^O177725
CQSAVE=^O177730
CQVERF=^O177733
CQSYS= ^O177736
ISCNTC=^O177741
CZGETL=^O177744 ;CALL POINT FOR "GET"
CQCALL=^O177747 ;CLOSE ALL CHANNELS
CQTIMR=^O215
BUFPAG==2
BUF==256BUFPAG
STKEND==507
CQSTAT=^O226
CQHTIM=^O164104
EXTIO==1
TIME==1
GETCMD==1
CLMWID==10
PI=255 ;VALUE OF PI CHARACTER FOR COMMODORE.
ROMSW==1
RORSW==1
TRMPOS=^O306>
IFE REALIO-1,<GETCMD==1
DISKO==1
OUTCH=^O17240 ;1EA0
ROMLOC==^O20000
RORSW==0
CZGETL=^O17132>
IFE REALIO-2,<
RORSW==0
RAMLOC==^O1000
IFN ROMSW,<
RORSW==0
RAMLOC==^O100000>
OUTCH==^O177013>
IFE REALIO-4,<
RORSW==1
NULCMD==0
GETCMD==1
CQINLN==^O176547
CQPRMP==^O63
CQINCH==^O176414
CQCOUT==^O177315
CQCSIN==^O177375
BUFPAG==2
BUF=BUFPAG256
ROMLOC=^O4000
RAMLOC=^O25000 ;PAGE 2A
OUTCH=^O176755
CZGETL=^O176414
LINLEN==40
BUFLEN==240
RORSW==1
STKEND=507>
IFE RORSW,<
DEFINE ROR (WD),<
LDAI 0
BCC .+4
LDAI ^O200
LSR WD
ORA WD
STA WD>>
DEFINE ACRLF,<
13
10>
DEFINE SYNCHK (Q),<
LDAI <Q>
JSR SYNCHR>
DEFINE DT(Q),<
IRPC Q,<IFDIF <Q><">,<EXP "Q">>>
DEFINE LDWD (WD),<
LDA WD
LDY <WD>+1>
DEFINE LDWDI (WD),<
LDAI <<WD>&^O377>
LDYI <<WD>/^O400>>
DEFINE LDWX (WD),<
LDA WD
LDX <WD>+1>
DEFINE LDWXI (WD),<
LDAI <<WD>&^O377>
LDXI <<WD>/^O400>>
DEFINE LDXY (WD),<
LDX WD
LDY <WD>+1>
DEFINE LDXYI (WD),<
LDXI <<WD>&^O377>
LDYI <<WD>/^O400>>
DEFINE STWD (WD),<
STA WD
STY <WD>+1>
DEFINE STWX (WD),<
STA WD
STX <WD>+1>
DEFINE STXY (WD),<
STX WD
STY <WD>+1>
DEFINE CLR (WD),<
LDAI 0
STA WD>
DEFINE COM (WD),<
LDA WD
EORI ^O377
STA WD>
DEFINE PULWD (WD),<
PLA
STA WD
PLA
STA <WD>+1>
DEFINE PSHWD (WD),<
LDA <WD>+1
PHA
LDA WD
PHA>
DEFINE JEQ (WD),<
BNE .+5
JMP WD>
DEFINE JNE (WD),<
BEQ .+5
JMP WD>
DEFINE BCCA(Q),< BCC Q> ;BRANCHES THAT ALWAYS BRANCH
DEFINE BCSA(Q),< BCS Q> ;THESE ARE USED ON THE 6502 BECAUSE
DEFINE BEQA(Q),< BEQ Q> ;THERE IS NO UNCONDITIONAL BRANCH
DEFINE BNEA(Q),< BNE Q>
DEFINE BMIA(Q),< BMI Q>
DEFINE BPLA(Q),< BPL Q>
DEFINE BVCA(Q),< BVC Q>
DEFINE BVSA(Q),< BVS Q>
DEFINE INCW(R),<
INC R
BNE %Q
INC R+1
%Q:>
DEFINE SKIP1, <XWD ^O1000,^O044> ;BIT ZERO PAGE TRICK.
DEFINE SKIP2, <XWD ^O1000,^O054> ;BIT ABS TRICK.
IF1,<
IFE REALIO,<PRINTX/SIMULATE/>
IFE REALIO-1,<PRINTX KIM>
IFE REALIO-2,<PRINTX OSI>
IFE REALIO-3,<PRINTX COMMODORE>
IFE REALIO-4,<PRINTX APPLE>
IFE REALIO-5,<PRINTX STM>
IFN ADDPRC,<PRINTX ADDITIONAL PRECISION>
IFN INTPRC,<PRINTX INTEGER ARRAYS>
IFN LNGERR,<PRINTX LONG ERRORS>
IFN DISKO,<PRINTX SAVE AND LOAD>
IFE ROMSW,<PRINTX RAM>
IFN ROMSW,<PRINTX ROM>
IFE RORSW,<PRINTX NO ROR>
IFN RORSW,<PRINTX ROR ASSUMED>>
PAGE
SUBTTL INTRODUCTION AND COMPILATION PARAMETERS.
COMMENT
--------- ---- -- ---------
COPYRIGHT 1976 BY MICROSOFT
--------- ---- -- ---------
7/27/78 FIXED BUG WHERE FOR VARIABLE AT BYTE FF MATCHED RETURN SEARCHING
FOR GOSUB ENTRY ON STACK IN FNDFOR CALL BY CHANGING STA FORPNT
TO STA FORPNT+1. THIS IS A SERIOUS BUG IN ALL VERSIONS.
7/27/78 FIXED BUG AT NEWSTT UNDER IFN BUFPAG WHEN CHECK OF CURLIN
WAS DONE BEFORE CURLIN SET UP SO INPUT RETRIES OF FIRST STATEMENT
WAS GIVING SYNTAX ERROR INSTEAD OF REDO FROM START (CODE WAS 12/1/77 FIX)
7/1/78 SAVED A FEW BYTES IN INIT FOR COMMODORE (14)
7/1/78 FIXED BUG WHERE REPLACING A LINE OVERFLOWING MEMORY LEFT LINKS
IN A BAD STATE. (CODE AT NODEL AND FINI) BUG#4
7/1/78 FIXED BUG WHERE GARBAGE COLLECTION NEVER(!) COLLECTS TEMPS
(STY GRBPNT AT FNDVAR, LDA GRBPNT ORA GRBPNT+1 AT GRBPAS)
THIS WAS COMMODORE BUG #2
7/1/78 FIXED BUG WHERE DELETE/INSERT OF LINE COULD CAUSE A GARBAGE COLLECTION WITH BAD VARTAB IF OUT OF MEMORY
(LDWD MEMSIZ STWD FRETOP=JSR RUNC CLC ALSO AT NODEL)
3/9/78 EDIT TO FIX COMMO TRMPOS AND CHANGE LEFT$ AND RIGHT$ TO ALLOW A SECOND ARGUMENT OF 0 AND RETURN A NULL STRING
2/25/78 FIXED BUG THAT INPFLG WAS SET WRONG WHEN BUFPAG.NE.0
INCREASED NUMLEV FROM 19 TO 23
2/11/78 DISALLOWED SPACES IN RESERVED WORDS. PUT IN SPECIAL CHECK FOR "GO TO"
2/11/78 FIXED BUG WHERE ROUNDING OF THE FAC BEFORE PUSHING COULD CAUSE A STRING POINTER
IN THE FAC TO BE INCREMENTED
1/24/78 fixed problem where user defined function undefined check fix was smashing error number in [x]
12/1/77 FIXED PROBLEM WHERE PEEK WAS SMASHING (POKER) CAUSING POKE OF PEEK TO FAIL
12/1/77 FIXED PROBLEM WHERE PROBLEM WITH VARTXT=LINNUM=BUF-2 CAUSING BUF-1 COMMA TO DISAPPEAR
12/1/77 FIXED BUFPAG.NE.0 PROBLEM AT NEWSTT AND STOP : CODE WAS STILL
ASSUMING TXTPTR+1.EQ.0 IFF STATEMENT WAS DIRECT
NUMLEV==23 ;NUMBER OF STACK LEVELS RESERVED
;BY AN EXPLICIT CALL TO "GETSTK".
STRSIZ==3 ;# OF LOCS PER STRING DESCRIPTOR.
NUMTMP==3 ;NUMBER OF STRING TEMPORARIES.
CONTW==15 ;CHARACTER TO SUPPRESS OUTPUT.
PAGE
SUBTTL SOME EXPLANATION.
COMMENT
M6502 BASIC CONFIGURES BASIC AS FOLLOWS
LOW LOCATIONS
PAGE ZERO
STARTUP:
INITIALLY A JMP TO INITIALIZATION CODE BUT
CHANGED TO A JMP TO "READY".
RESTARTING THE MACHINE AT LOC 0 DURING PROGRAM
EXECUTION CAN LEAVE THINGS MESSED UP.
LOC OF FAC TO INTEGER AND INTEGER TO FAC
ROUTINES.
"DIRECT" MEMORY:
THESE ARE THE MOST COMMONLY USED LOCATIONS.
THEY HOLD BOOKKEEPING INFO AND ALL OTHER
FREQUENTLY USED INFORMATION.
ALL TEMPORARIES, FLAGS, POINTERS, THE BUFFER AREA,
THE FLOATING ACCUMULATOR, AND ANYTHING ELSE THAT
IS USED TO STORE A CHANGING VALUE SHOULD BE LOCATED
IN THIS AREA. CARE MUST BE MADE IN MOVING LOCATIONS
IN THIS AREA SINCE THE JUXTAPOSITION OF TWO LOCATIONS
IS OFTEN DEPENDED UPON.
STILL IN RAM WE HAVE THE BEGINNING OF THE "CHRGET"
SUBROUTINE. IT IS HERE SO [TXTPTR] CAN BE THE
EXTENDED ADDRESS OF A LOAD INSTRUCTION.
THIS SAVES HAVING TO BOTHER ANY REGISTERS.
PAGE ONE
THE STACK.
STORAGE PAGE TWO AND ON
IN RAM VERSIONS THESE DATA STRUCTURES COME AT THE
END OF BASIC. IN ROM VERSON THEY ARE AT RAMLOC WHICH
CAN EITHER BE ABOVE OR BELOW ROMLOC, WHICH IS WHERE
BASIC ITSELF RESIDES.
A ZERO.
[TXTTAB] POINTER TO NEXT LINE'S POINTER.
LINE # OF THIS LINE (2 BYTES).
CHARACTERS ON THIS LINE.
ZERO.
POINTER AT NEXT LINE'S POINTER
(POINTED TO BY THE ABOVE POINTER).
... REPEATS ...
LAST LINE: POINTER AT ZERO POINTER.
LINE # OF THIS LINE.
CHARACTERS ON THIS LINE.
ZERO.
DOUBLE ZERO (POINTED TO BY THE ABOVE POINTER).
[VARTAB] SIMPLE VARIABLES. 6 BYTES PER VALUE.
2 BYTES GIVE THE NAME, 4 BYTES THE VALUE.
... REPEATS ...
[ARYTAB] ARRAY VARIABLES. 2 BYTES NAME, 2 BYTE
LENGTH, NUMBER OF DIMENSIONS , EXTENT OF
EACH DIMENSION (2BYTES/), VALUES
... REPEATS ...
[STREND] FREE SPACE.
... REPEATS ...
[FRETOP] STRING SPACE IN USE.
... REPEATS ...
[MEMSIZ] HIGHEST MACHINE LOCATION.
UNUSED EXCEPT BY THE VAL FUNCTION.
ROM -- CONSTANTS AND CODE.
FUNCTION DISPATCH ADDRESSES (AT ROMLOC)
"FUNDSP" CONTAINS THE ADDRESSES OF THE
FUNCTION ROUTINES IN THE ORDER OF THE
FUNCTION NAMES IN THE CRUNCH LIST.
THE FUNCTIONS THAT TAKE MORE THAN ONE ARGUMENT
ARE AT THE END. SEE THE EXPLANATION AT "ISFUN".
THE OPERATOR LIST
THE "OPTAB" LIST CONTAINS AN OPERATOR'S PRECEDENCE
FOLLOWED BY THE ADDRESS OF THE ROUTINE TO PERFORM
THE OPERATION. THE INDEX INTO THE
OPERATOR LIST IS MADE BY SUBTRACTING OFF THE CRUNCH VALUE
OF THE LOWEST NUMBERED OPERATOR. THE ORDER
OF OPERATORS IN THE CRUNCH LIST AND IN "OPTAB" IS IDENTICAL.
THE PRECEDENCES ARE ARBITRARY EXCEPT FOR THEIR
COMPARATIVE SIZES. NOTE THAT THE PRECEDENCE FOR
UNARY OPERATORS SUCH AS "NOT" AND NEGATION ARE
SETUP SPECIALLY WITHOUT USING THE LIST.
THE RESERVED WORD OR CRUNCH LIST
WHEN A COMMAND OR PROGRAM LINE IS TYPED IN
IT IS STORED IN "BUF". AS SOON AS THE WHOLE LINE
HAS BEEN TYPED IN ("INLIN" RETURNS) "CRUNCH" IS
CALLED TO CONVERT ALL RESERVED WORDS TO THEIR
CRUNCHED VALUES. THIS REDUCES THE SIZE OF THE
PROGRAM AND SPEEDS UP EXECUTION BY ALLOWING
LIST DISPATCHES TO PERFORM FUNCTIONS, STATEMENTS,
AND OPERATIONS. THIS IS BECAUSE ALL THE STATEMENT
NAMES ARE STORED CONSECUTIVELY IN THE CRUNCH LIST.
WHEN A MATCH IS FOUND BETWEEN A STRING
OF CHARACTERS AND A WORD IN THE CRUNCH LIST
THE ENTIRE TEXT OF THE MATCHED WORD IS TAKEN OUT OF
THE INPUT LINE AND A RESERVED WORD TOKEN IS PUT
IN ITS PLACE. A RESERVED WORD TOKEN IS ALWAYS EQUAL
TO OCTAL 200 PLUS THE POSITION OF THE MATCHED WORD
IN THE CRUNCH LIST.
STATEMENT DISPATCH ADDRESSES
WHEN A STATEMENT IS TO BE EXECUTED, THE FIRST
CHARACTER OF THE STATEMENT IS EXAMINED
TO SEE IF IT IS LESS THAN THE RESERVED
WORD TOKEN FOR THE LOWEST NUMBERED STATEMENT NAME.
IF SO, THE "LET" CODE IS CALLED TO
TREAT THE STATEMENT AS AN ASSIGNMENT STATEMENT.
OTHERWISE A CHECK IS MADE TO MAKE SURE THE
RESERVED WORD NUMBER IS NOT TOO LARGE TO BE A
STATEMENT TYPE NUMBER. IF NOT THE ADDRESS
TO DISPATCH TO IS FETCHED FROM "STMDSP" (THE STATEMENT
DISPATCH LIST) USING THE RESERVED WORD
NUMBER FOR THE STATEMENT TO CALCULATE AN INDEX INTO
THE LIST.
ERROR MESSAGES
WHEN AN ERROR CONDITION IS DETECTED,
[ACCX] MUST BE SET UP TO INDICATE WHICH ERROR
MESSAGE IS APPROPRIATE AND A BRANCH MUST BE MADE
TO "ERROR". THE STACK WILL BE RESET AND ALL
PROGRAM CONTEXT WILL BE LOST. VARIABLES
VALUES AND THE ACTUAL PROGRAM REMAIN INTACT.
ONLY THE VALUE OF [ACCX] IS IMPORTANT WHEN
THE BRANCH IS MADE TO ERROR. [ACCX] IS USED AS AN
INDEX INTO "ERRTAB" WHICH GIVES THE TWO
CHARACTER ERROR MESSAGE THAT WILL BE PRINTED ON THE
USER'S TERMINAL.
TEXTUAL MESSAGES
CONSTANT MESSAGES ARE STORED HERE. UNLESS
THE CODE TO CHECK IF A STRING MUST BE COPIED
IS CHANGED THESE STRINGS MUST BE STORED ABOVE
PAGE ZERO, OR ELSE THEY WILL BE COPIED BEFORE
THEY ARE PRINTED.
FNDFOR
MOST SMALL ROUTINES ARE FAIRLY SIMPLE
AND ARE DOCUMENTED IN PLACE. "FNDFOR" IS
USED FOR FINDING "FOR" ENTRIES ON
THE STACK. WHENEVER A "FOR" IS EXECUTED, A
16-BYTE ENTRY IS PUSHED ONTO THE STACK.
BEFORE THIS IS DONE, HOWEVER, A CHECK
MUST BE MADE TO SEE IF THERE
ARE ANY "FOR" ENTRIES ALREADY ON THE STACK
FOR THE SAME LOOP VARIABLE. IF SO, THAT "FOR" ENTRY
AND ALL OTHER "FOR" ENTRIES THAT WERE MADE AFTER IT
ARE ELIMINATED FROM THE STACK. THIS IS SO A
PROGRAM THAT JUMPS OUT OF THE MIDDLE
OF A "FOR" LOOP AND THEN RESTARTS THE LOOP AGAIN
AND AGAIN WON'T USE UP 18 BYTES OF STACK
SPACE EVERY TIME. THE "NEXT" CODE ALSO
CALLS "FNDFOR" TO SEARCH FOR A "FOR" ENTRY WITH
THE LOOP VARIABLE IN
THE "NEXT". AT WHATEVER POINT A MATCH IS FOUND
THE STACK IS RESET. IF NO MATCH IS FOUND A
"NEXT WITHOUT FOR" ERROR OCCURS. GOSUB EXECUTION
ALSO PUTS A 5-BYTE ENTRY ON STACK.
WHEN A RETURN IS EXECUTED "FNDFOR" IS
CALLED WITH A VARIABLE POINTER THAT CAN'T
BE MATCHED. WHEN "FNDFOR" HAS RUN
THROUGH ALL THE "FOR" ENTRIES ON THE STACK
IT RETURNS AND THE RETURN CODE MAKES
SURE THE ENTRY THAT WAS STOPPED
ON IS A GOSUB ENTRY. THIS ASSURES THAT
IF YOU GOSUB TO A SECTION OF CODE
IN WHICH A FOR LOOP IS ENTERED BUT NEVER
EXITED THE RETURN WILL STILL BE
ABLE TO FIND THE MOST RECENT
GOSUB ENTRY. THE "RETURN" CODE ELIMINATES THE
"GOSUB" ENTRY AND ALL "FOR" ENTRIES MADE AFTER
THE GOSUB ENTRY.
NON-RUNTIME STUFF
THE CODE TO INPUT A LINE, CRUNCH IT, GIVE ERRORS,
FIND A SPECIFIC LINE IN THE PROGRAM,
PERFORM A "NEW", "CLEAR", AND "LIST" ARE
ALL IN THIS AREA. GIVEN THE EXPLANATION OF
PROGRAM STORAGE SET FORTH ABOVE, THESE ARE
ALL STRAIGHTFORWARD.
NEWSTT
WHENEVER A STATEMENT FINISHES EXECUTION IT
DOES A "RTS" WHICH TAKES
EXECUTION BACK TO "NEWSTT". STATEMENTS THAT
CREATE OR LOOK AT SEMI-PERMANENT STACK ENTRIES
MUST GET RID OF THE RETURN ADDRESS OF "NEWSTT" AND
JMP TO "NEWSTT" WHEN DONE. "NEWSTT" ALWAYS
CHRGETS THE FIRST CHARACTER AFTER THE STATEMENT
NAME BEFORE DISPATCHING. WHEN RETURNING
BACK TO "NEWSTT" THE ONLY THING THAT
MUST BE SET UP IS THE TEXT POINTER IN
"TXTPTR". "NEWSTT" WILL CHECK TO MAKE SURE
"TXTPTR" IS POINTING TO A STATEMENT TERMINATOR.
IF A STATEMENT SHOULDN'T BE PERFORMED UNLESS
IT IS PROPERLY FORMATTED (I.E. "NEW") IT CAN
SIMPLY DO A RETURN AFTER READING ALL OF
ITS ARGUMENTS. SINCE THE ZERO FLAG
BEING OFF INDICATES THERE IS NOT
A STATEMENT TERMINATOR "NEWSTT" WILL
DO THE JMP TO THE "SYNTAX ERROR"
ROUTINE. IF A STATEMENT SHOULD BE STARTED
OVER IT CAN DO LDWD OLDTXT, STWD TXTPTR RTS SINCE THE TEXT PNTR
AT "NEWSTT" IS ALWAYS STORED IN "OLDTXT".
THE ^C CODE STORES [CURLIN] (THE
CURRENT LINE NUMBER) IN "OLDLIN" SINCE THE ^C CHECK
IS MADE BEFORE THE STATEMENT POINTED TO IS
EXECUTED. "STOP" AND "END" STORE THE TEXT POINTER
FROM "TXTPTR", WHICH POINTS AT THEIR TERMINATING
CHARACTER, IN "OLDTXT".
STATEMENT CODE
THE INDIVIDUAL STATEMENT CODE COMES
NEXT. THE APPROACH USED IN EXECUTING EACH
STATEMENT IS DOCUMENTED IN THE STATEMENT CODE
ITSELF.
FRMEVL, THE FORMULA EVALUATOR
GIVEN A TEXT POINTER POINTING TO THE STARTING
CHARACTER OF A FORMULA, "FRMEVL"
EVALUATES THE FORMULA AND LEAVES
THE VALUE IN THE FLOATING ACCUMULATOR (FAC).
"TXTPTR" IS RETURNED POINTING TO THE FIRST CHARACTER
THAT COULD NOT BE INTERPRETED AS PART OF THE
FORMULA. THE ALGORITHM USES THE STACK
TO STORE TEMPORARY RESULTS:
0. PUT A DUMMY PRECEDENCE OF ZERO ON
THE STACK.
1. READ LEXEME (CONSTANT,FUNCTION,
VARIABLE,FORMULA IN PARENS)
AND TAKE THE LAST PRECEDENCE VALUE
OFF THE STACK.
2. SEE IF THE NEXT CHARACTER IS AN OPERATOR.
IF NOT, CHECK PREVIOUS ONE. THIS MAY CAUSE
OPERATOR APPLICATION OR AN ACTUAL
RETURN FROM "FRMEVL".
3. IF IT IS, SEE WHAT PRECEDENCE IT HAS
AND COMPARE IT TO THE PRECEDENCE
OF THE LAST OPERATOR ON THE STACK.
4. IF = OR LESS REMEMBER THE OPERATOR
POINTER OF THIS OPERATOR
AND BRANCH TO "QCHNUM" TO CAUSE
APPLICATION OF THE LAST OPERATOR.
EVENTUALLY RETURN TO STEP 2
BY RETURNING TO JUST AFTER "DOPREC".
5. IF GREATER PUT THE LAST PRECEDENCE
BACK ON, SAVE THE OPERATOR ADDRESS,
CURRENT TEMPORARY RESULT,
AND PRECEDENCE AND RETURN TO STEP 1.
RELATIONAL OPERATORS ARE ALL HANDLED THROUGH
A COMMON ROUTINE. SPECIAL
CARE IS TAKEN TO DETECT TYPE MISMATCHES SUCH AS 3+"F".
EVAL -- THE ROUTINE TO READ A LEXEME
"EVAL" CHECKS FOR THE DIFFERENT TYPES OF
ENTITIES IT IS SUPPOSED TO DETECT.
LEADING PLUSES ARE IGNORED,
DIGITS AND "." CAUSE "FIN" (FLOATING INPUT)
TO BE CALLED. FUNCTION NAMES CAUSE THE
FORMULA INSIDE THE PARENTHESES TO BE EVALUATED
AND THE FUNCTION ROUTINE TO BE CALLED. VARIABLE
NAMES CAUSE "PTRGET" TO BE CALLED TO GET A POINTER
TO THE VALUE, AND THEN THE VALUE IS PUT INTO
THE FAC. AN OPEN PARENTHESIS CAUSES "FRMEVL"
TO BE CALLED (RECURSIVELY), AND THE ")" TO
BE CHECKED FOR. UNARY OPERATORS (NOT AND
NEGATION) PUT THEIR PRECEDENCE ON THE STACK
AND ENTER FORMULA EVALUATION AT STEP 1, SO
THAT EVERYTHING UP TO AN OPERATOR GREATER THAN
THEIR PRECEDENCE OR THE END OF THE FORMULA
WILL BE EVALUATED.
DIMENSION AND VARIABLE SEARCHING
SPACE IS ALLOCATED FOR VARIABLES AS THEY ARE
ENCOUNTERED. THUS "DIM" STATEMENTS MUST BE
EXECUTED TO HAVE EFFECT. 6 BYTES ARE ALLOCATED
FOR EACH SIMPLE VARIABLE, WHETHER IT IS A STRING,
NUMBER OR USER DEFINED FUNCTION. THE FIRST TWO
BYTES GIVE THE NAME OF THE VARIABLE AND THE LAST FOUR
GIVE ITS VALUE. [VARTAB] GIVES THE FIRST LOCATION
WHERE A SIMPLE VARIABLE NAME IS FOUND AND [ARYTAB]
GIVES THE LOCATION TO STOP SEARCHING FOR SIMPLE
VARIABLES. A "FOR" ENTRY HAS A TEXT POINTER
AND A POINTER TO A VARIABLE VALUE SO NEITHER
THE PROGRAM OR THE SIMPLE VARIABLES CAN BE
MOVED WHILE THERE ARE ACTIVE "FOR" ENTRIES ON THE STACK.
USER DEFINED FUNCTION VALUES ALSO CONTAIN
POINTERS INTO SIMPLE VARIABLE SPACE SO NO USER-DEFINED
FUNCTION VALUES CAN BE RETAINED IF SIMPLE VARIABLES
ARE MOVED. ADDING A SIMPLE VARIABLE IS JUST
ADDING SIX TO [ARYTAB] AND [STREND], BLOCK TRANSFERING
THE ARRAY VARIABLES UP BY SIX AND MAKING SURE THE
NEW [STREND] IS NOT TOO CLOSE TO THE STRINGS.
THIS MOVEMENT OF ARRAY VARIABLES MEANS
THAT NO POINTER TO AN ARRAY WILL STAY VALID WHEN
NEW SIMPLE VARIABLES CAN BE ENCOUNTERED. THIS IS
WHY ARRAY VARIABLES ARE NOT ALLOWED FOR "FOR"
LOOP VARIABLES. SETTING UP A NEW ARRAY VARIABLE
MERELY INVOLVES BUILDING THE DESCRIPTOR,
UPDATING [STREND], AND MAKING SURE THERE IS
STILL ENOUGH ROOM BETWEEN [STREND] AND STRING SPACE.
"PTRGET", THE ROUTINE WHICH RETURNS A POINTER
TO A VARIABLE VALUE, HAS TWO IMPORTANT FLAGS. ONE IS
"DIMFLG" WHICH INDICATES WHETHER "DIM" CALLED "PTRGET"
OR NOT. IF SO, NO PRIOR ENTRY FOR THE VARIABLE IN
QUESTION SHOULD BE FOUND, AND THE INDEX INDICATES
HOW MUCH SPACE TO SET ASIDE. SIMPLE VARIABLES CAN
BE "DIMENSIONED", BUT THE ONLY EFFECT WILL BE TO
SET ASIDE SPACE FOR THE VARIABLE IF IT HASN'T BEEN
ENCOUNTERED YET. THE OTHER IMPORTANT FLAG IS "SUBFLG"
WHICH INDICATES WHETHER A SUBSCRIPTED VARIABLE SHOULD BE
ALLOWED IN THE CURRENT CONTEXT. IF [SUBFLG] IS NON-ZERO
THE OPEN PARENTHESIS FOR A SUBSCRIPTED VARIABLE
WILL NOT BE SCANNED BY "PTRGET", AND "PTRGET" WILL RETURN
WITH A TEXT POINTER POINTING TO THE "(", IF
THERE WAS ONE.
STRINGS
IN THE VARIABLE TABLES STRINGS ARE STORED JUST LIKE
NUMERIC VARIABLES. SIMPLE STRINGS HAVE THREE VALUE
BYTES WHICH ARE INITIALIZED TO ALL ZEROS (WHICH
REPRESENTS THE NULL STRING). THE ONLY DIFFERENCE
IN HANDLING IS THAT WHEN "PTRGET" SEES A "$" AFTER THE
NAME OF A VARIABLE, "PTRGET" SETS [VALTYP]
TO NEGATIVE ONE AND TURNS
ON THE MSB (MOST-SIGNIFIGANT-BIT) OF THE VALUE OF
THE FIRST CHARACTER OF THE VARIABLE NAME.
HAVING THIS BIT ON IN THE NAME OF THE VARIABLE ENSURES
THAT THE SEARCH ROUTINE WILL NOT MATCH
'A' WITH 'A$' OR 'A$' WITH 'A'. THE MEANING OF
THE THREE VALUE BYTES ARE:
LOW
LENGTH OF THE STRING
LOW 8 BITS
HIGH 8 BITS OF THE ADDRESS
OF THE CHARACTERS IN THE
STRING IF LENGTH.NE.0.
MEANINGLESS OTHERWISE.
HIGH
THE VALUE OF A STRING VARIABLE (THESE 3 BYTES)
IS CALLED THE STRING DESCRIPTOR TO DISTINGUISH
IT FROM THE ACTUAL STRING DATA. WHENEVER A
STRING CONSTANT IS ENCOUNTERED IN A FORMULA OR AS
PART OF AN INPUT STRING, OR AS PART OF DATA, "STRLIT"
IS CALLED, CAUSING A DESCRIPTOR TO BE BUILT FOR
THE STRING. WHEN ASSIGNMENT IS MADE TO A STRING POINTING INTO
"BUF" THE VALUE IS COPIED INTO STRING SPACE SINCE [BUF]
IS ALWAYS CHANGING.
STRING FUNCTIONS AND THE ONE STRING OPERATOR "+"
ALWAYS RETURN THEIR VALUES IN STRING SPACE.
ASSIGNING A STRING A CONSTANT VALUE IN A PROGRAM
THROUGH A "READ" OR ASSIGNMENT STATEMENT
WILL NOT USE ANY STRING SPACE SINCE
THE STRING DESCRIPTOR WILL POINT INTO THE
PROGRAM ITSELF. IN GENERAL, COPYING IS DONE
WHEN A STRING VALUE IS IN "BUF", OR IT IS IN STRING
SPACE AND THERE IS AN ACTIVE POINTER TO IT.
THUS F$=G$ WILL CAUSE COPYING IF G$ HAS ITS
STRING DATA IN STRING SPACE. F$=CHR$(7)
WILL USE ONE BYTE OF STRING SPACE TO STORE THE
NEW ONE CHARACTER STRING CREATED BY "CHR$", BUT
THE ASSIGNMENT ITSELF WILL CAUSE NO COPYING SINCE
THE ONLY POINTER AT THE NEW STRING IS A
TEMPORARY DESCRIPTOR CREATED BY "FRMEVL" WHICH WILL
GO AWAY AS SOON AS THE ASSIGNMENT IS DONE.
IT IS THE NATURE OF GARBAGE COLLECTION THAT
DISALLOWS HAVING TWO STRING DESCRIPTORS POINT TO THE SAME
AREA IN STRING SPACE. STRING FUNCTIONS AND OPERATORS
MUST PROCEED AS FOLLOWS:
1) FIGURE OUT THE LENGTH OF THEIR RESULT.
2) CALL "GETSPA" TO FIND SPACE FOR THEIR
RESULT. THE ARGUMENTS TO THE FUNCTION
OR OPERATOR MAY CHANGE SINCE GARBAGE COLLECTION
MAY BE INVOKED. THE ONLY THING THAT CAN
BE SAVED DURING THE CALL TO "GETSPA" IS A POINTER
TO THE DESCRIPTORS OF THE ARGUMENTS.
3) CONSTRUCT THE RESULT DESCRIPTOR IN "DSCTMP".
"GETSPA" RETURNS THE LOCATION OF THE AVAILABLE
SPACE.
4) CREATE THE NEW VALUE BY COPYING PARTS
OF THE ARGUMENTS OR WHATEVER.
5) FREE UP THE ARGUMENTS BY CALLING "FRETMP".
6) JUMP TO "PUTNEW" TO GET THE DESCRIPTOR IN
"DSCTMP" TRANSFERRED INTO A NEW STRING TEMPORARY.
THE REASON FOR STRING TEMPORARIES IS THAT GARBAGE
COLLECTION HAS TO KNOW ABOUT ALL ACTIVE STRING DESCRIPTORS
SO IT KNOWS WHAT IS AND ISN'T IN USE. STRING TEMPORARIES ARE
USED TO STORE THE DESCRIPTORS OF STRING EXPRESSIONS.
INSTEAD OF HAVING AN ACTUAL VALUE STORED IN THE
FAC, AND HAVING THE VALUE OF A TEMPORARY RESULT
BEING SAVED ON THE STACK, AS HAPPENS WITH NUMERIC
VARIABLES, STRINGS HAVE THE POINTER TO A STRING DESCRIPTOR
STORED IN THE FAC, AND IT IS THIS POINTER
THAT GETS SAVED ON THE STACK BY FORMULA EVALUATION.
STRING FUNCTIONS CANNOT FREE THEIR ARGUMENTS UP RIGHT
AWAY SINCE "GETSPA" MAY FORCE
GARBAGE COLLECTION AND THE ARGUMENT STRINGS
MAY BE OVER-WRITTEN SINCE GARBAGE COLLECTION
WILL NOT BE ABLE TO FIND AN ACTIVE POINTER TO
THEM. FUNCTION AND OPERATOR RESULTS ARE BUILT IN
"DSCTMP" SINCE STRING TEMPORARIES ARE ALLOCATED
(PUTNEW) AND DEALLOCATED (FRETMP) IN A FIFO ORDERING
(I.E. A STACK) SO THE NEW TEMPORARY CANNOT
BE SET UP UNTIL THE OLD ONE(S) ARE FREED. TRYING
TO BUILD A RESULT IN A TEMPORARY AFTER
FREEING UP THE ARGUMENT TEMPORARIES COULD RESULT
IN ONE OF THE ARGUMENT TEMPORARIES BEING OVERWRITTEN
TOO SOON BY THE NEW RESULT.
STRING SPACE IS ALLOCATED AT THE VERY TOP
OF MEMORY. "MEMSIZ" POINTS BEYOND THE LAST LOCATION OF
STRING SPACE. STRINGS ARE STORED IN HIGH LOCATIONS
FIRST. WHENEVER STRING SPACE IS ALLOCATED (GETSPA).
[FRETOP], WHICH IS INITIALIZED TO [MEMSIZ], IS UPDATED
TO GIVE THE HIGHEST LOCATION IN STRING SPACE
THAT IS NOT IN USE. THE RESULT IS THAT
[FRETOP] GETS SMALLER AND SMALLER, UNTIL SOME
ALLOCATION WOULD MAKE [FRETOP] LESS THAN OR EQUAL TO
[STREND]. THIS MEANS STRING SPACE HAS RUN INTO THE
THE ARRAYS AND THAT GARBAGE COLLECTION MUST BE CALLED.
GARBAGE COLLECTION:
0. [MINPTR]=[STREND] [FRETOP]=[MEMSIZ]
1. [REMMIN]=0
2. FOR EACH STRING DESCRIPTOR
(TEMPORARIES, SIMPLE STRINGS, STRING ARRAYS)
IF THE STRING IS NOT NULL AND ITS POINTER IS
.GT.MINPTR AND .LT.FRETOP,
[MINPTR]=THIS STRING DESCRIPTOR'S POINTER,
[REMMIN]=POINTER AT THIS STRING DESCRIPTOR.
END.
3. IF REMMIN.NE.0 (WE FOUND AN UNCOLLECTED STRING),
BLOCK TRANSFER THE STRING DATA POINTED
TO IN THE STRING DESCRIPTOR POINTED TO BY "REMMIN"
SO THAT THE LAST BYTE OF STRING DATA IS AT
[FRETOP]. UPDATE [FRETOP] SO THAT IT
POINTS TO THE LOCATION JUST BELOW THE ONE
THE STRING DATA WAS MOVED INTO. UPDATE
THE POINTER IN THE DESCRIPTOR SO IT POINTS
TO THE NEW LOCATION OF THE STRING DATA.
GO TO STEP 1.
AFTER CALLING GARBAGE COLLECTION "GETSPA" AGAIN CHECKS
TO SEE IF [ACCA] CHARACTERS ARE AVAILABLE BETWEEN
[STREND] AND [FRETOP]; IF NOT, AN "OUT OF STRING"
ERROR IS INVOKED.
MATH PACKAGE
THE MATH PACKAGE CONTAINS FLOATING INPUT (FIN),
FLOATING OUTPUT (FOUT), FLOATING COMPARE (FCOMP)
... AND ALL THE NUMERIC OPERATORS AND FUNCTIONS.
THE FORMATS, CONVENTIONS AND ENTRY POINTS ARE ALL
DESCRIBED IN THE MATH PACKAGE ITSELF.
INIT -- THE INITIALIZATION ROUTINE
THE AMOUNT OF MEMORY,
TERMINAL WIDTH, AND WHICH FUNCTIONS TO BE RETAINED
ARE ASCERTAINED FROM THE USER. A ZERO IS PUT DOWN
AT THE FIRST LOCATION NOT USED BY THE MATH-PACKAGE
AND [TXTTAB] IS SET UP TO POINT AT THE NEXT LOCATION.
THIS DETERMINES WHERE PROGRAM STORAGE WILL START.
SPECIAL CHECKS ARE MADE TO MAKE SURE
ALL QUESTIONS IN "INIT" ARE ANSWERED REASONABLY, SINCE
ONCE "INIT" FINISHES, THE LOCATIONS IT USES ARE
USED FOR PROGRAM STORAGE. THE LAST THING "INIT" DOES IS
CHANGE LOCATION ZERO TO BE A JUMP TO "READY" INSTEAD
OF "INIT". ONCE THIS IS DONE THERE IS NO WAY TO RESTART
"INIT".
HIGH LOCATIONS
PAGE
SUBTTL PAGE ZERO.
IFN REALIO-3,<
START: JMP INIT ;INITIALIZE - SETUP CERTAIN LOCATIONS
;AND DELETE FUNCTIONS IF NOT NEEDED,
;AND CHANGE THIS TO "JMP READY"
;IN CASE USER RESTARTS AT LOC ZERO.
RDYJSR: JMP INIT ;CHANGED TO "JMP STROUT" BY "INIT"
;TO HANDLE ERRORS.
ADRAYI: ADR(AYINT) ;STORE HERE THE ADDR OF THE
;ROUTINE TO TURN THE FAC INTO A
;TWO BYTE SIGNED INTEGER IN [Y,A]
ADRGAY: ADR(GIVAYF)> ;STORE HERE THE ADDR OF THE
;ROUTINE TO CONVERT [Y,A] TO A FLOATING
;POINT NUMBER IN THE FAC.
IFN ROMSW,<
USRPOK: JMP FCERR> ;SET UP ORIG BY INIT.
;
; THIS IS THE "VOLATILE" STORAGE AREA AND NONE OF IT
; CAN BE KEPT IN ROM. ANY CONSTANTS IN THIS AREA CANNOT
; BE KEPT IN A ROM, BUT MUST BE LOADED IN BY THE
; PROGRAM INSTRUCTIONS IN ROM.
;
; --- GENERAL RAM ---:
CHARAC: BLOCK 1 ;A DELIMITING CHARACTER.
INTEGR= CHARAC ;A ONE-BYTE INTEGER FROM "QINT".
ENDCHR: BLOCK 1 ;THE OTHER DELIMITING CHARACTER.
COUNT: BLOCK 1 ;A GENERAL COUNTER.
; --- FLAGS ---:
DIMFLG: BLOCK 1 ;IN GETTING A POINTER TO A VARIABLE
;IT IS IMPORTANT TO REMEMBER WHETHER IT
;IS BEING DONE FOR "DIM" OR NOT.
;DIMFLG AND VALTYP MUST BE
;CONSECUTIVE LOCATIONS.
KIMY= DIMFLG ;PLACE TO PRESERVE Y DURING OUT.
VALTYP: BLOCK 1 ;THE TYPE INDICATOR.
;0=NUMERIC 1=STRING.
IFN INTPRC,<
INTFLG: BLOCK 1> ;TELLS IF INTEGER.
DORES: BLOCK 1 ;WHETHER CAN OR CAN'T CRUNCH RES'D WORDS.
;TURNED ON WHEN "DATA"
;BEING SCANNED BY CRUNCH SO UNQUOTED
;STRINGS WON'T BE CRUNCHED.
GARBFL= DORES ;WHETHER TO DO GARBAGE COLLECTION.
SUBFLG: BLOCK 1 ;FLAG WHETHER SUB'D VARIABLE ALLOWED.
;"FOR" AND USER-DEFINED FUNCTION
;POINTER FETCHING TURN
;THIS ON BEFORE CALLING "PTRGET"
;SO ARRAYS WON'T BE DETECTED.
;"STKINI" AND "PTRGET" CLEAR IT.
;ALSO DISALLOWS INTEGERS THERE.
INPFLG: BLOCK 1 ;FLAGS WHETHER WE ARE DOING "INPUT"
;OR "READ".
TANSGN: BLOCK 1 ;USED IN DETERMINING SIGN OF TANGENT.
IFN REALIO,<
CNTWFL: BLOCK 1> ;SUPPRESS OUTPUT FLAG.
;NON-ZERO MEANS SUPPRESS.
;RESET BY "INPUT", READY AND ERRORS.
;COMPLEMENTED BY INPUT OF ^O.
IFE REALIO-4,<ORG 80> ;ROOM FOR APPLE PAGE 0 STUFF.
; --- RAM DEALING WITH TERMINAL HANDLING ---:
IFN EXTIO,<
CHANNL: BLOCK 1> ;HOLDS CHANNEL NUMBER.
IFN NULCMD,<
NULCNT: 0> ;NUMBER OF NULLS TO PRINT.
IFN REALIO-3,<
TRMPOS: BLOCK 1> ;POSITION OF TERMINAL CARRIAGE.
LINWID: LINLEN ;LENGTH OF LINE (WIDTH).
NCMWID: NCMPOS ;POSITION BEYOND WHICH THERE ARE
;NO MORE FIELDS.
LINNUM: 0 ;LOCATION TO STORE LINE NUMBER BEFORE BUF
;SO THAT "BLTUC" CAN STORE IT ALL AWAY AT ONCE.
44 ;A COMMA (PRELOAD OR FROM ROM)
;USED BY INPUT STATEMENT SINCE THE
;DATA POINTER ALWAYS STARTS ON A
;COMMA OR TERMINATOR.
IFE BUFPAG,<
BUF: BLOCK BUFLEN> ;TYPE IN STORED HERE.
;DIRECT STATEMENTS EXECUTE OUT OF
;HERE. REMEMBER "INPUT" SMASHES BUF.
;MUST BE ON PAGE ZERO
;OR ASSIGNMENT OF STRING
;VALUES IN DIRECT STATEMENTS WON'T COPY
;INTO STRING SPACE -- WHICH IT MUST.
;N.B. TWO NONZERO BYTES MUST PRECEDE "BUFLNM".
; --- STORAGE FOR TEMPORARY THINGS ---:
TEMPPT: BLOCK 1 ;POINTER AT FIRST FREE TEMP DESCRIPTOR.
;INITIALIZED TO POINT TO TEMPST.
LASTPT: BLOCK 2 ;POINTER TO LAST-USED STRING TEMPORARY.
TEMPST: BLOCK STRSIZNUMTMP ;STORAGE FOR NUMTMP TEMP DESCRIPTORS.
INDEX1: BLOCK 2 ;INDEXES.
INDEX= INDEX1
INDEX2: BLOCK 2
RESHO: BLOCK 1 ;RESULT OF MULTIPLIER AND DIVIDER.
IFN ADDPRC,<
RESMOH: BLOCK 1> ;ONE MORE BYTE.
RESMO: BLOCK 1
RESLO: BLOCK 1
ADDEND= RESMO ;TEMPORARY USED BY "UMULT".
0 ;OVERFLOW FOR RES.
; --- POINTERS INTO DYNAMIC DATA STRUCTURES ---;
TXTTAB: BLOCK 2 ;POINTER TO BEGINNING OF TEXT.
;DOESN'T CHANGE AFTER BEING
;SETUP BY "INIT".
VARTAB: BLOCK 2 ;POINTER TO START OF SIMPLE
;VARIABLE SPACE.
;UPDATED WHENEVER THE SIZE OF THE
;PROGRAM CHANGES, SET TO [TXTTAB]
;BY "SCRATCH" ("NEW").
ARYTAB: BLOCK 2 ;POINTER TO BEGINNING OF ARRAY
;TABLE.
;INCREMENTED BY 6 WHENEVER
;A NEW SIMPLE VARIABLE IS FOUND, AND
;SET TO [VARTAB] BY "CLEARC".
STREND: BLOCK 2 ;END OF STORAGE IN USE.
;INCREASED WHENEVER A NEW ARRAY
;OR SIMPLE VARIABLE IS ENCOUNTERED.
;SET TO [VARTAB] BY "CLEARC".
FRETOP: BLOCK 2 ;TOP OF STRING FREE SPACE.
FRESPC: BLOCK 2 ;POINTER TO NEW STRING.
MEMSIZ: BLOCK 2 ;HIGHEST LOCATION IN MEMORY.
; --- LINE NUMBERS AND TEXTUAL POINTERS ---:
CURLIN: BLOCK 2 ;CURRENT LINE #.
;SET TO 0,255 FOR DIRECT STATEMENTS.
OLDLIN: BLOCK 2 ;OLD LINE NUMBER (SETUP BY ^C,"STOP"
;OR "END" IN A PROGRAM).
POKER= LINNUM ;SET UP LOCATION USED BY POKE.
;TEMPORARY FOR INPUT AND READ CODE
OLDTXT: BLOCK 2 ;OLD TEXT POINTER.
;POINTS AT STATEMENT TO BE EXEC'D NEXT.
DATLIN: BLOCK 2 ;DATA LINE # -- REMEMBER FOR ERRORS.
DATPTR: BLOCK 2 ;POINTER TO DATA. INITIALIZED TO POINT
;AT THE ZERO IN FRONT OF [TXTTAB]
;BY "RESTORE" WHICH IS CALLED BY "CLEARC".
;UPDATED BY EXECUTION OF A "READ".
INPPTR: BLOCK 2 ;THIS REMEMBERS WHERE INPUT IS COMING FROM.
; --- STUFF USED IN EVALUATIONS ---:
VARNAM: BLOCK 2 ;VARIABLE'S NAME IS STORED HERE.
VARPNT: BLOCK 2 ;POINTER TO VARIABLE IN MEMORY.
FDECPT= VARPNT ;POINTER INTO POWER OF TENS OF "FOUT".
FORPNT: BLOCK 2 ;A VARIABLE'S POINTER FOR "FOR" LOOPS
;AND "LET" STATEMENTS.
LSTPNT= FORPNT ;PNTR TO LIST STRING.
ANDMSK= FORPNT ;THE MASK USED BY WAIT FOR ANDING.
EORMSK= FORPNT+1 ;THE MASK FOR EORING IN WAIT.
OPPTR: BLOCK 2 ;POINTER TO CURRENT OP'S ENTRY IN "OPTAB".
VARTXT= OPPTR ;POINTER INTO LIST OF VARIABLES.
OPMASK: BLOCK 1 ;MASK CREATED BY CURRENT OPERATOR.
DOMASK=TANSGN ;MASK IN USE BY RELATION OPERATIONS.
DEFPNT: BLOCK 2 ;POINTER USED IN FUNCTION DEFINITION.
GRBPNT= DEFPNT ;ANOTHER USED IN GARBAGE COLLECTION.
DSCPNT: BLOCK 2 ;POINTER TO A STRING DESCRIPTOR.
IFN ADDPRC,<BLOCK 1> ;FOR TEMPF3.
FOUR6: EXP STRSIZ ;VARIABLE CONSTANT USED BY GARB COLLECT.
; --- ET CETERA ---:
JMPER: JMP 60000
SIZE= JMPER+1
OLDOV= JMPER+2 ;THE OLD OVERFLOW.
TEMPF3= DEFPNT ;A THIRD FAC TEMPORARY (4 BYTES).
TEMPF1:
IFN ADDPRC,<0> ;FOR TEMPF1S EXTRA BYTE.
HIGHDS: BLOCK 2 ;DESINATION OF HIGHEST ELEMENT IN BLT.
HIGHTR: BLOCK 2 ;SOURCE OF HIGHEST ELEMENT TO MOVE.
TEMPF2:
IFN ADDPRC,<0> ;FOR TEMPF2S EXTRA BYTE.
LOWDS: BLOCK 2 ;LOCATION OF LAST BYTE TRANSFERRED INTO.
LOWTR: BLOCK 2 ;LAST THING TO MOVE IN BLT.
ARYPNT= HIGHDS ;A POINTER USED IN ARRAY BUILDING.
GRBTOP= LOWTR ;A POINTER USED IN GARBAGE COLLECTION.
DECCNT= LOWDS ;NUMBER OF PLACES BEFORE DECIMAL POINT.
TENEXP= LOWDS+1 ;HAS A DPT BEEN INPUT?
DPTFLG= LOWTR ;BASE TEN EXPONENT.
EXPSGN= LOWTR+1 ;SIGN OF BASE TEN EXPONENT.
; --- THE FLOATING ACCUMULATOR ---:
FAC:
FACEXP: 0
FACHO: 0 ;MOST SIGNIFICANT BYTE OF MANTISSA.
IFN ADDPRC,<
FACMOH: 0> ;ONE MORE.
FACMO: 0 ;MIDDLE ORDER OF MANTISSA.
FACLO: 0 ;LEAST SIG BYTE OF MANTISSA.
FACSGN: 0 ;SIGN OF FAC (0 OR -1) WHEN UNPACKED.
SGNFLG: 0 ;SIGN OF FAC IS PRESERVED BERE BY "FIN".
DEGREE= SGNFLG ;A COUNT USED BY POLYNOMIALS.
DSCTMP= FAC ;THIS IS WHERE TEMP DESCS ARE BUILT.
INDICE= FACMO ;INDICE IS SET UP HERE BY "QINT".
BITS: 0 ;SOMETHING FOR "SHIFTR" TO USE.
; --- THE FLOATING ARGUMENT (UNPACKED) ---:
ARGEXP: 0
ARGHO: 0
IFN ADDPRC,<ARGMOH: 0>
ARGMO: 0
ARGLO: 0
ARGSGN: 0
ARISGN: 0 ;A SIGN REFLECTING THE RESULT.
FACOV: 0 ;OVERFLOW BYTE OF THE FAC.
STRNG1= ARISGN ;POINTER TO A STRING OR DESCRIPTOR.
FBUFPT: BLOCK 2 ;POINTER INTO FBUFFR USED BY FOUT.
BUFPTR= FBUFPT ;POINTER TO BUF USED BY "CRUNCH".
STRNG2= FBUFPT ;POINTER TO STRING OR DESC.
POLYPT= FBUFPT ;POINTER INTO POLYNOMIAL COEFFICIENTS.
CURTOL= FBUFPT ;ABSOLUTE LINEAR INDEX IS FORMED HERE.
PAGE
SUBTTL RAM CODE.
; THIS CODE GETS CHANGED THROUGHOUT EXECUTION.
; IT IS MADE TO BE FAST THIS WAY.
; ALSO, [X] AND [Y] ARE NOT DISTURBED
;
; "CHRGET" USING [TXTPTR] AS THE CURRENT TEXT PNTR
; FETCHES A NEW CHARACTER INTO ACCA AFTER INCREMENTING [TXTPTR]
; AND SETS CONDITION CODES ACCORDING TO WHAT'S IN ACCA.
; NOT C= NUMERIC ("0" THRU "9")
; Z= ":" OR END-OF-LINE (A NULL)
;
; [ACCA] = NEW CHAR.
; [TXTPTR]=[TXTPTR]+1
;
; THE FOLLOWING EXISTS IN ROM IF ROM EXISTS AND IS LOADED
; DOWN HERE BY INIT. OTHERWISE IT IS JUST LOADED INTO THIS
; RAM LIKE ALL THE REST OF RAM IS LOADED.
;
CHRGET: INC CHRGET+7 ;INCREMENT THE WHOLE TXTPTR.
BNE CHRGOT
INC CHRGET+8
CHRGOT: LDA 60000 ;A LOAD WITH AN EXT ADDR.
TXTPTR= CHRGOT+1
CMPI " " ;SKIP SPACES.
BEQ CHRGET
QNUM: CMPI ":" ;IS IT A ":"?
BCS CHRRTS ;IT IS .GE. ":"
SEC
SBCI "0" ;ALL CHARS .GT. "9" HAVE RET'D SO
SEC
SBCI 256-"0" ;SEE IF NUMERIC.
;TURN CARRY ON IF NUMERIC.
;ALSO, SETZ IF NULL.
CHRRTS: RTS ;RETURN TO CALLER.
RNDX: 128 ;LOADED OR FROM ROM.
79 ;THE INITIAL RANDOM NUMBER.
199
82
IFN ADDPRC,<89> ;ONE MORE BYTE.
ORG 255 ;PAGE 1 STUFF COMING UP.
LOFBUF: BLOCK 1 ;THE LOW FAC BUFFER. COPYABLE.
;--- PAGE ZERO/ONE BOUNDARY ---.
;MUST HAVE 13 CONTIGUOUS BYTES.
FBUFFR: BLOCK 3ADDPRC+13 ;BUFFER FOR "FOUT".
;ON PAGE 1 SO THAT STRING IS NOT COPIED.
;STACK IS LOCATED HERE. IE FROM THE END OF FBUFFR TO STKEND.
PAGE
SUBTTL DISPATCH TABLES, RESERVED WORDS, AND ERROR TEXTS.
ORG ROMLOC
STMDSP: ADR(END-1)
ADR(FOR-1)
ADR(NEXT-1)
ADR(DATA-1)
IFN EXTIO,<
ADR(INPUTN-1)>
ADR(INPUT-1)
ADR(DIM-1)
ADR(READ-1)
ADR(LET-1)
ADR(GOTO-1)
ADR(RUN-1)
ADR(IF-1)
ADR(RESTORE-1)
ADR(GOSUB-1)
ADR(RETURN-1)
ADR(REM-1)
ADR(STOP-1)
ADR(ONGOTO-1)
IFN NULCMD,<
ADR(NULL-1)>
ADR(FNWAIT-1)
IFN DISKO,<
IFE REALIO-3,<
ADR(CQLOAD-1)
ADR(CQSAVE-1)
ADR(CQVERF-1)>
IFN REALIO,<
IFN REALIO-2,<
IFN REALIO-3,<
IFN REALIO-5,<
ADR(LOAD-1)
ADR(SAVE-1)>>>>
IFN REALIO-1,<
IFN REALIO-3,<
IFN REALIO-4,<
ADR(511) ;ADDRESS OF LOAD
ADR(511)>>>> ;ADDRESS OF SAVE
ADR(DEF-1)
ADR(POKE-1)
IFN EXTIO,<
ADR(PRINTN-1)>
ADR(PRINT-1)
ADR(CONT-1)
IFE REALIO,<
ADR(DDT-1)>
ADR(LIST-1)
ADR(CLEAR-1)
IFN EXTIO,<
ADR(CMD-1)
ADR(CQSYS-1)
ADR(CQOPEN-1)
ADR(CQCLOS-1)>
IFN GETCMD,<
ADR(GET-1)> ;FILL W/ GET ADDR.
ADR(SCRATH-1)
FUNDSP: ADR(SGN)
ADR(INT)
ADR(ABS)
IFE ROMSW,<
USRLOC: ADR(FCERR)> ;INITIALLY NO USER ROUTINE.
IFN ROMSW,<
USRLOC: ADR(USRPOK)>
ADR(FRE)
ADR(POS)
ADR(SQR)
ADR(RND)
ADR(LOG)
ADR(EXP)
IFN KIMROM,<
REPEAT 4,<
ADR(FCERR)>>
IFE KIMROM,<
COSFIX: ADR(COS)
SINFIX: ADR(SIN)
TANFIX: ADR(TAN)
ATNFIX: ADR(ATN)>
ADR(PEEK)
ADR(LEN)
ADR(STR)
ADR(VAL)
ADR(ASC)
ADR(CHR)
ADR(LEFT)
ADR(RIGHT)
ADR(MID)
OPTAB: 121
ADR(FADDT-1)
121
ADR(FSUBT-1)
123
ADR(FMULTT-1)
123
ADR(FDIVT-1)
127
ADR(FPWRT-1)
80
ADR(ANDOP-1)
70
ADR(OROP-1)
NEGTAB: 125
ADR(NEGOP-1)
NOTTAB: 90
ADR(NOTOP-1)
PTDORL: 100 ;PRECEDENCE.
ADR (DOREL-1) ;OPERATOR ADDRESS.
;
; TOKENS FOR RESERVED WORDS ALWAYS HAVE THE MOST
; SIGNIFICANT BIT ON.
; THE LIST OF RESERVED WORDS:
;
Q=128-1
DEFINE DCI(A),<Q=Q+1
DC(A)>
RESLST: DCI"END"
ENDTK==Q
DCI"FOR"
FORTK==Q
DCI"NEXT"
DCI"DATA"
DATATK==Q
IFN EXTIO,<
DCI"INPUT#">
DCI"INPUT"
DCI"DIM"
DCI"READ"
DCI"LET"
DCI"GOTO"
GOTOTK==Q
DCI"RUN"
DCI"IF"
DCI"RESTORE"
DCI"GOSUB"
GOSUTK=Q
DCI"RETURN"
DCI"REM"
REMTK=Q
DCI"STOP"
DCI"ON"
IFN NULCMD,<
DCI"NULL">
DCI"WAIT"
IFN DISKO,<
DCI"LOAD"
DCI"SAVE"
IFE REALIO-3,<
DCI"VERIFY">>
DCI"DEF"
DCI"POKE"
IFN EXTIO,<
DCI"PRINT#">
DCI"PRINT"
PRINTK==Q
DCI"CONT"
IFE REALIO,<
DCI"DDT">
DCI"LIST"
IFN REALIO-3,<
DCI"CLEAR">
IFE REALIO-3,<
DCI"CLR">
IFN EXTIO,<
DCI"CMD"
DCI"SYS"
DCI"OPEN"
DCI"CLOSE">
IFN GETCMD,<
DCI"GET">
DCI"NEW"
SCRATK=Q
; END OF COMMAND LIST.
"T"
"A"
"B"
"("+128
Q=Q+1
TABTK=Q
DCI"TO"
TOTK==Q
DCI"FN"
FNTK==Q
"S"
"P"
"C"
"("+128 ;MACRO DOESNT LIKE ('S IN ARGUMENTS.
Q=Q+1
SPCTK==Q
DCI"THEN"
THENTK=Q
DCI"NOT"
NOTTK==Q
DCI"STEP"
STEPTK=Q
DCI"+"
PLUSTK=Q
DCI"-"
MINUTK=Q
DCI""
DCI"/"
DCI"^"
DCI"AND"
DCI"OR"
190 ;A GREATER THAN SIGN
Q=Q+1
GREATK=Q
DCI"="
EQULTK=Q
188
Q=Q+1 ;A LESS THAN SIGN
LESSTK=Q
;
; NOTE DANGER OF ONE RESERVED WORD BEING A PART
; OF ANOTHER:
; IE . . IF 2 GREATER THAN F OR T=5 THEN...
; WILL NOT WORK!!! SINCE "FOR" WILL BE CRUNCHED!!
; IN ANY CASE MAKE SURE THE SMALLER WORD APPEARS
; SECOND IN THE RESERVED WORD TABLE ("INP" AND "INPUT")
; ANOTHER EXAMPLE: IF T OR Q THEN ... "TO" IS CRUNCHED
;
DCI"SGN"
ONEFUN=Q
DCI"INT"
DCI"ABS"
DCI"USR"
DCI"FRE"
DCI"POS"
DCI"SQR"
DCI"RND"
DCI"LOG"
DCI"EXP"
DCI"COS"
DCI"SIN"
DCI"TAN"
DCI"ATN"
DCI"PEEK"
DCI"LEN"
DCI"STR$"
DCI"VAL"
DCI"ASC"
DCI"CHR$"
LASNUM==Q ;NUMBER OF LAST FUNCTION
;THAT TAKES ONE ARG
DCI"LEFT$"
DCI"RIGHT$"
DCI"MID$"
DCI"GO"
GOTK==Q
0 ;MARKS END OF RESERVED WORD LIST
IFE LNGERR,<
Q=0-2
DEFINE DCE(X),<Q=Q+2
DC(X)>
ERRTAB: DCE"NF"
ERRNF==Q ;NEXT WITHOUT FOR.
DCE"SN"
ERRSN==Q ;SYNTAX
DCE"RG"
ERRRG==Q ;RETURN WITHOUT GOSUB.
DCE"OD"
ERROD==Q ;OUT OF DATA.
DCE"FC"
ERRFC==Q ;ILLEGAL QUANTITY.
DCE"OV"
ERROV==Q ;OVERFLOW.
DCE"OM"
ERROM==Q ;OUT OF MEMORY.
DCE"US"
ERRUS==Q ;UNDEFINED STATEMENT.
DCE"BS"
ERRBS==Q ;BAD SUBSCRIPT.
DCE"DD"
ERRDD==Q ;REDIMENSIONED ARRAY.
DCE"/0"
ERRDV0==Q ;DIVISION BY ZERO.
DCE"ID"
ERRID==Q ;ILLEGAL DIRECT.
DCE"TM"
ERRTM==Q ;TYPE MISMATCH.
DCE"LS"
ERRLS==Q ;STRING TOO LONG.
IFN EXTIO,<
DCE"FD" ;FILE DATA.
ERRBD==Q>
DCE"ST"
ERRST==Q ;STRING FORMULA TOO COMPLEX.
DCE"CN"
ERRCN==Q ;CAN'T CONTINUE.
DCE"UF"
ERRUF==Q> ;UNDEFINED FUNCTION.
IFN LNGERR,<
Q=0
; NOTE: THIS ERROR COUNT TECHNIQUE WILL NOT WORK IF THERE ARE MORE
; THAN 256 CHARACTERS OF ERROR MESSAGES
ERRTAB: DC"NEXT WITHOUT FOR"
ERRNF==Q
Q=Q+16
DC"SYNTAX"
ERRSN==Q
Q=Q+6
DC"RETURN WITHOUT GOSUB"
ERRRG==Q
Q=Q+20
DC"OUT OF DATA"
ERROD==Q
Q=Q+11
DC"ILLEGAL QUANTITY"
ERRFC==Q
Q=Q+16
DC"OVERFLOW"
ERROV==Q
Q=Q+8
DC"OUT OF MEMORY"
ERROM==Q
Q=Q+13
DC"UNDEF'D STATEMENT"
ERRUS==Q
Q=Q+17
DC"BAD SUBSCRIPT"
ERRBS==Q
Q=Q+13
DC"REDIM'D ARRAY"
ERRDD==Q
Q=Q+13
DC"DIVISION BY ZERO"
ERRDV0==Q
Q=Q+16
DC"ILLEGAL DIRECT"
ERRID==Q
Q=Q+14
DC"TYPE MISMATCH"
ERRTM==Q
Q=Q+13
DC"STRING TOO LONG"
ERRLS==Q
Q=Q+15
IFN EXTIO,<
DC"FILE DATA"
ERRBD==Q
Q=Q+9>
DC"FORMULA TOO COMPLEX"
ERRST==Q
Q=Q+19
DC"CAN'T CONTINUE"
ERRCN==Q
Q=Q+14
DC"UNDEF'D FUNCTION"
ERRUF==Q>
;
; NEEDED FOR MESSAGES IN ALL VERSIONS.
;
ERR: DT" ERROR"
0
INTXT: DT" IN "
0
REDDY: ACRLF
IFE REALIO-3,<
DT"READY.">
IFN REALIO-3,<
DT"OK">
ACRLF
0
BRKTXT: ACRLF
DT"BREAK"
0
PAGE
SUBTTL GENERAL STORAGE MANAGEMENT ROUTINES.
;
; FIND A "FOR" ENTRY ON THE STACK VIA "VARPNT".
;
FORSIZ==2ADDPRC+16
FNDFOR: TSX ;LOAD XREG WITH STK PNTR.
REPEAT 4,<INX> ;IGNORE ADR(NEWSTT) AND RTS ADDR.
FFLOOP: LDA 257,X ;GET STACK ENTRY.
CMPI FORTK ;IS IT A "FOR" TOKEN?
BNE FFRTS ;NO, NO "FOR" LOOPS WITH THIS PNTR.
LDA FORPNT+1 ;GET HIGH.
BNE CMPFOR
LDA 258,X ;PNTR IS ZERO, SO ASSUME THIS ONE.
STA FORPNT
LDA 259,X
STA FORPNT+1
CMPFOR: CMP 259,X
BNE ADDFRS ;NOT THIS ONE.
LDA FORPNT ;GET DOWN.
CMP 258,X
BEQ FFRTS ;WE GOT IT! WE GOT IT!
ADDFRS: TXA
CLC ;ADD 16 TO X.
ADCI FORSIZ
TAX ;RESULT BACK INTO X.
BNE FFLOOP
FFRTS: RTS ;RETURN TO CALLER.
;
; THIS IS THE BLOCK TRANSFER ROUTINE.
; IT MAKES SPACE BY SHOVING EVERYTHING FORWARD.
;
; ON ENTRY:
; [Y,A]=[HIGHDS] (FOR REASON).
; [HIGHDS]= DESTINATION OF [HIGH ADDRESS].
; [LOWTR]= LOWEST ADDR TO BE TRANSFERRED.
; [HIGHTR]= HIGHEST ADDR TO BE TRANSFERRED.
;
; A CHECK IS MADE TO ASCERTAIN THAT A REASONABLE
; AMOUNT OF SPACE REMAINS BETWEEN THE BOTTOM
; OF THE STRINGS AND THE HIGHEST LOCATION TRANSFERRED INTO.
;
; ON EXIT:
; [LOWTR] ARE UNCHANGED.
; [HIGHTR]=[LOWTR]-200 OCTAL.
; [HIGHDS]=LOWEST ADDR TRANSFERRED INTO MINUS 200 OCTAL.
;
BLTU: JSR REASON ;ASCERTAIN THAT STRING SPACE WON'T
;BE OVERRUN.
STWD STREND
BLTUC: SEC ;PREPARE TO SUBTRACT.
LDA HIGHTR
SBC LOWTR ;COMPUTE NUMBER OF THINGS TO MOVE.
STA INDEX ;SAVE FOR LATER.
TAY
LDA HIGHTR+1
SBC LOWTR+1
TAX ;PUT IT IN A COUNTER REGISTER.
INX ;SO THAT COUNTER ALGORITHM WORKS.
TYA ;SEE IF LOW PART OF COUNT IS ZERO.
BEQ DECBLT ;YES, GO START MOVING BLOCKS.
LDA HIGHTR ;NO, MUST MODIFY BASE ADDR.
SEC
SBC INDEX ;BORROW IS OFF SINCE [HIGHTR].GT.[LOWTR].
STA HIGHTR ;SAVE MODIFIED BASE ADDR.
BCS BLT1 ;IF NO BORROW, GO SHOVE IT.
DEC HIGHTR+1 ;BORROW IMPLIES SUB 1 FROM HIGH ORDER.
SEC
BLT1: LDA HIGHDS ;MOD BASE OF DEST ADDR.
SBC INDEX
STA HIGHDS
BCS MOREN1 ;NO BORROW.
DEC HIGHDS+1 ;DECREMENT HIGH ORDER BYTE.
BCC MOREN1 ;ALWAYS SKIP.
BLTLP: LDADY HIGHTR ;FETCH BYTE TO MOVE
STADY HIGHDS ;MOVE IT IN, MOVE IT OUT.
MOREN1: DEY
BNE BLTLP
LDADY HIGHTR ;MOVE LAST OF THE BLOCK.
STADY HIGHDS
DECBLT: DEC HIGHTR+1
DEC HIGHDS+1 ;START ON NEW BLOCKS.
DEX
BNE MOREN1
RTS ;RETURN TO CALLER.
;
; THIS ROUTINE IS USED TO ASCERTAIN THAT A GIVEN
; NUMBER OF LOCS REMAIN AVAILABLE FOR THE STACK.
; THE CALL IS:
; LDAI NUMBER OF 2-BYTE ENTRIES NEEDED.
; JSR GETSTK
;
; THIS ROUTINE MUST BE CALLED BY ANY ROUTINE WHICH PUTS
; AN ARBITRARY AMOUNT OF STUFF ON THE STACK,
; I.E., ANY RECURSIVE ROUTINE LIKE "FRMEVL".
; IT IS ALSO CALLED BY ROUTINES SUCH AS "GOSUB" AND "FOR"
; WHICH MAKE PERMANENT ENTRIES ON THE STACK.
;
; ROUTINES WHICH MERELY USE AND FREE UP THE GUARANTEED
; NUMLEV LOCATIONS NEED NOT CALL THIS.
;
;
; ON EXIT:
; [A] AND [X] HAVE BEEN MODIFIED.
;
GETSTK: ASL A, ;MULT [A] BY 2. NB, CLEARS C BIT.
ADCI 2NUMLEV+<3ADDPRC>+13 ;MAKE SURE 2NUMLEV+13 LOCS
;(13 BECAUSE OF FBUFFR)
BCS OMERR ;WILL REMAIN IN STACK.
STA INDEX
TSX ;GET STACKED.
CPX INDEX ;COMPARE.
BCC OMERR ;IF STACK.LE.INDEX1, OM.
RTS
;
; [Y,A] IS A CERTAIN ADDRESS. "REASON" MAKES SURE
; IT IS LESS THAN [FRETOP].
;
REASON: CPY FRETOP+1
BCC REARTS
BNE TRYMOR ;GO GARB COLLECT.
CMP FRETOP
BCC REARTS
TRYMOR: PHA
LDXI 8+ADDPRC ;IF TEMPF2 HAS ZERO IN BETWEEN.
TYA
REASAV: PHA
LDA HIGHDS-1,X ;SAVE HIGHDS ON STACK.
DEX
BPL REASAV ;PUT 8 OF THEM ON STK.
JSR GARBA2 ;GO GARB COLLECT.
LDXI 256-8-ADDPRC
REASTO: PLA
STA HIGHDS+8+ADDPRC,X ;RESTORE AFTER GARB COLLECT.
INX
BMI REASTO
PLA
TAY
PLA ;RESTORE A AND Y.
CPY FRETOP+1 ;COMPARE HIGHS
BCC REARTS
BNE OMERR ;HIGHER IS BAD.
CMP FRETOP ;AND THE LOWS.
BCS OMERR
REARTS: RTS
PAGE
SUBTTL ERROR HANDLER, READY, TERMINAL INPUT, COMPACTIFY, NEW, REINIT.
OMERR: LDXI ERROM
ERROR:
IFN REALIO,<
LSR CNTWFL> ;FORCE OUTPUT.
IFN EXTIO,<
LDA CHANNL ;CLOSE NON-TERMINAL CHANNEL.
BEQ ERRCRD
JSR CQCCHN ;CLOSE IT.
LDAI 0
STA CHANNL>
ERRCRD: JSR CRDO ;OUTPUT CRLF.
JSR OUTQST ;PRINT A QUESTION MARK
IFE LNGERR,<
LDA ERRTAB,X, ;GET FIRST CHR OF ERR MSG.
JSR OUTDO ;OUTPUT IT.
LDA ERRTAB+1,X, ;GET SECOND CHR.
JSR OUTDO> ;OUTPUT IT.
IFN LNGERR,<
GETERR: LDA ERRTAB,X
PHA
ANDI 127 ;GET RID OF HIGH BIT.
JSR OUTDO ;OUTPUT IT.
INX
PLA ;LAST CHAR OF MESSAGE?
BPL GETERR> ;NO. GO GET NEXT AND OUTPUT IT.
TYPERR: JSR STKINI ;RESET THE STACK AND FLAGS.
LDWDI ERR ;GET PNTR TO " ERROR".
ERRFIN: JSR STROUT ;OUTPUT IT.
LDY CURLIN+1
INY ;WAS NUMBER 64000?
BEQ READY ;YES, DON'T TYPE LINE NUMBER.
JSR INPRT
READY:
IFN REALIO,<
LSR CNTWFL> ;TURN OUTPUT BACK ON IF SUPRESSED
LDWDI REDDY ;SAY "OK".
IFN REALIO-3,<
JSR RDYJSR> ;OR GO TO INIT IF INIT ERROR.
IFE REALIO-3,<
JSR STROUT> ;NO INIT ERRORS POSSIBLE.
MAIN: JSR INLIN ;GET A LINE FROM TERMINAL.
STXY TXTPTR
JSR CHRGET
TAX ;SET ZERO FLAG BASED ON [A]
;THIS DISTINGUISHES ":" AND 0
BEQ MAIN ;IF BLANK LINE, GET ANOTHER.
LDXI 255 ;SET DIRECT LINE NUMBER.
STX CURLIN+1
BCC MAIN1 ;IS A LINE NUMBER. NOT DIRECT.
JSR CRUNCH ;COMPACTIFY.
JMP GONE ;EXECUTE IT.
MAIN1: JSR LINGET ;READ LINE NUMBER INTO "LINNUM".
JSR CRUNCH
STY COUNT ;RETAIN CHARACTER COUNT.
JSR FNDLIN
BCC NODEL ;NO MATCH, SO DON'T DELETE.
LDYI 1
LDADY LOWTR
STA INDEX1+1
LDA VARTAB
STA INDEX1
LDA LOWTR+1 ;SET TRANSFER TO.
STA INDEX2+1
LDA LOWTR
DEY
SBCDY LOWTR ;COMPUTE NEGATIVE LENGTH.
CLC
ADC VARTAB ;COMPUTE NEW VARTAB.
STA VARTAB
STA INDEX2 ;SET LOW OF TRANS TO.
LDA VARTAB+1
ADCI 255
STA VARTAB+1 ;COMPUTE HIGH OF VARTAB.
SBC LOWTR+1 ;COMPUTE NUMBER OF BLOCKS TO MOVE.
TAX
SEC
LDA LOWTR
SBC VARTAB ;COMPUTE OFFSET.
TAY
BCS QDECT1 ;IF VARTAB.LE.LOWTR,
INX ;DECR DUE TO CARRY, AND
DEC INDEX2+1 ;DECREMENT STORE SO CARRY WORKS.
QDECT1: CLC
ADC INDEX1
BCC MLOOP
DEC INDEX1+1
CLC ;FOR LATER ADCQ
MLOOP: LDADY INDEX1
STADY INDEX2
INY
BNE MLOOP ;BLOCK DONE?
INC INDEX1+1
INC INDEX2+1
DEX
BNE MLOOP ;DO ANOTHER BLOCK. ALWAYS.
NODEL: JSR RUNC ;RESET ALL VARIABLE INFO SO GARBAGE
;COLLECTION CAUSED BY REASON WILL WORK
JSR LNKPRG ;FIX UP THE LINKS
LDA BUF ;SEE IF ANYTHNG THERE
BEQ MAIN
CLC
LDA VARTAB
STA HIGHTR ;SETUP HIGHTR.
ADC COUNT ;ADD LENGTH OF LINE TO INSERT.
STA HIGHDS ;THIS GIVES DEST ADDR.
LDY VARTAB+1
STY HIGHTR+1 ;SAME FOR HIGH ORDERS.
BCC NODELC
INY
NODELC: STY HIGHDS+1
JSR BLTU
IFN BUFPAG,<
LDWD LINNUM ;POSITION THE BINARY LINE NUMBER
STWD BUF-2> ;IN FRONT OF BUF
LDWD STREND
STWD VARTAB
LDY COUNT
DEY
STOLOP: LDA BUF-4,Y
STADY LOWTR
DEY
BPL STOLOP
FINI: JSR RUNC ;DO CLEAR & SET UP STACK.
;AND SET [TXTPTR] TO [TXTTAB]-1.
JSR LNKPRG ;FIX UP PROGRAM LINKS
JMP MAIN
LNKPRG: LDWD TXTTAB ;SET [INDEX] TO [TXTTAB].
STWD INDEX
CLC
;
; CHEAD GOES THROUGH PROGRAM STORAGE AND FIXES
; UP ALL THE LINKS. THE END OF EACH LINE IS FOUND
; BY SEARCHING FOR THE ZERO AT THE END.
; THE DOUBLE ZERO LINK IS USED TO DETECT THE END OF THE PROGRAM.
;
CHEAD: LDYI 1
LDADY INDEX ;ARRIVED AT DOUBLE ZEROES?
BEQ LNKRTS
LDYI 4
CZLOOP: INY ;THERE IS AT LEAST ONE BYTE.
LDADY INDEX
BNE CZLOOP ;NO, CONTINUE SEARCHING.
INY ;GO ONE BEYOND.
TYA
ADC INDEX
TAX
LDYI 0
STADY INDEX
LDA INDEX+1
ADCI 0
INY
STADY INDEX
STX INDEX
STA INDEX+1
BCCA CHEAD ;ALWAYS BRANCHES.
LNKRTS: RTS
;
; THIS IS THE LINE INPUT ROUTINE.
; IT READS CHARACTERS INTO BUF USING BACKARROW (UNDERSCORE, OR
; SHIFT O) AS THE DELETE CHARACTER AND @ AS THE
; LINE DELETE CHARACTER. IF MORE THAN BUFLEN CHARACTERS
; ARE TYPED, NO ECHOING IS DONE UNTIL A BACKARROW OR @ OR CR
; IS TYPED. CONTROL-G WILL BE TYPED FOR EACH EXTRA CHARACTER.
; THE ROUTINE IS ENTERED AT INLIN.
;
IFE REALIO-4,<
INLIN: LDXI 128 ;NO PROMPT CHARACTER
STX CQPRMP
JSR CQINLN ;GET A LINE ONTO PAGE 2
CPXI BUFLEN-1
BCS GDBUFS ;NOT TOO MANY CHARACTERS
LDXI BUFLEN-1
GDBUFS: LDAI 0 ;PUT A ZERO AT THE END
STA BUF,X
TXA
BEQ NOCHR
LOPBHT: LDA BUF-1,X
ANDI 127
STA BUF-1,X
DEX
BNE LOPBHT
NOCHR: LDAI 0
LDXYI <BUF-1> ;POINT AT THE BEGINNING
RTS>
IFN REALIO-4,<
IFN REALIO-3,<
LINLIN: IFE REALIO-2,<
JSR OUTDO> ;ECHO IT.
DEX ;BACKARROW SO BACKUP PNTR AND
BPL INLINC ;GET ANOTHER IF COUNT IS POSITIVE.
INLINN: IFE REALIO-2,<
JSR OUTDO> ;PRINT THE @ OR A SECOND BACKARROW
;IF THERE WERE TOO MANY.
JSR CRDO>
INLIN: LDXI 0
INLINC: JSR INCHR ;GET A CHARACTER.
IFN REALIO-3,<
CMPI 7 ;IS IT BOB ALBRECHT RINGING THE BELL
;FOR SCHOOL KIDS?
BEQ GOODCH>
CMPI 13 ;CARRIAGE RETURN?
BEQ FININ1 ;YES, FINISH UP.
IFN REALIO-3,<
CMPI 32 ;CHECK FOR FUNNY CHARACTERS.
BCC INLINC
CMPI 125 ;IS IT TILDA OR DELETE?
BCS INLINC ;BIG BAD ONES TOO.
CMPI "@" ;LINE DELETE?
BEQ INLINN ;YES.
CMPI "_" ;CHARACTER DELETE?
BEQ LINLIN> ;YES.
GOODCH:
IFN REALIO-3,<
CPXI BUFLEN-1 ;LEAVE ROOM FOR NULL.
;COMMO ASSURES US NEVER MORE THAN BUFLEN.
BCS OUTBEL>
STA BUF,X
INX
IFE REALIO-2,<SKIP2>
IFN REALIO-2,<BNE INLINC>
IFN REALIO-3,<
OUTBEL: LDAI 7
IFN REALIO,<
JSR OUTDO> ;ECHO IT.
BNE INLINC> ;CYCLE ALWAYS.
FININ1: JMP FININL> ;GO TO FININL FAR, FAR AWAY.
INCHR:
IFE REALIO-3,<
JSR CQINCH> ;FOR COMMODORE.
IFE REALIO-2,<
INCHRL: LDA ^O176000
REPEAT 4,<NOP>
LSR A,
BCC INCHRL
LDA ^O176001 ;GET THE CHARACTER.
REPEAT 4,<NOP>
ANDI 127>
IFE REALIO-1,<
JSR ^O17132> ;1E5A FOR MOS TECH.
IFE REALIO-4,<
JSR CQINCH ;FD0C FOR APPLE COMPUTER.
ANDI 127>
IFE REALIO,<
TJSR INSIM##> ;GET A CHARACTER FROM SIMULATOR
IFN REALIO,<
IFN EXTIO,<
LDY CHANNL ;CNT-O HAS NO EFFECT IF NOT FROM TERM.
BNE INCRTS>
CMPI CONTW ;SUPPRESS OUTPUT CHARACTER (^W).
BNE INCRTS ;NO, RETURN.
PHA
COM CNTWFL ;COMPLEMENT ITS STATE.
PLA>
INCRTS: RTS ;END OF INCHR.
;
; ALL "RESERVED" WORDS ARE TRANSLATED INTO SINGLE
; BYTES WITH THE MSB ON. THIS SAVES SPACE AND TIME
; BY ALLOWING FOR TABLE DISPATCH DURING EXECUTION.
; THEREFORE ALL STATEMENTS APPEAR TOGETHER IN THE
; RESERVED WORD LIST IN THE SAME ORDER THEY
; APPEAR IN STMDSP.
;
BUFOFS=0 ;THE AMOUNT TO OFFSET THE LOW BYTE
;OF THE TEXT POINTER TO GET TO BUF
;AFTER TXTPTR HAS BEE