( go.asm):00001 ******************************************************************************* ( go.asm):00002 * TurbOS ( go.asm):00003 ******************************************************************************* ( go.asm):00004 * See LICENSE.txt for licensing information. ( go.asm):00005 ******************************************************************** ( go.asm):00006 * ( go.asm):00007 * Edt/Rev YYYY/MM/DD Modified by ( go.asm):00008 * Comment ( go.asm):00009 * ------------------------------------------------------------------ ( go.asm):00010 * 1 2023/08/29 BGP ( go.asm):00011 * Created. ( go.asm):00012 * 2026/06/25 Codex ( go.asm):00013 * Annotated source and normalized comments. ( go.asm):00014 ( go.asm):00015 nam go ; name this module "go" ( go.asm):00016 ttl Very simple initial program ; set listing title ( go.asm):00017 ( go.asm):00018 use defs.d ; include TurbOS and CoCo definitions ( defs.d):00001 * Assemble-time capability flags ( defs.d):00002 * ( defs.d):00003 * Feature Flags - eliminating one or more of these capabilities saves code space. ( defs.d):00004 * ( defs.d):00005 * Manage your own interrupts or install interrupt service routines using F$IRQ. 0001 ( defs.d):00006 _FF_IRQ_POLL equ 1 Set to 1 for interrupt service routine polling ( defs.d):00007 ( defs.d):00008 * Use virtual interrupt service routines using F$VIRQ. 0001 ( defs.d):00009 _FF_VIRQ_POLL equ 1 Set to 1 for virtual interrupt service routine polling ( defs.d):00010 ( defs.d):00011 * Wall time gives year/month/date/hour/minute/second support. 0001 ( defs.d):00012 _FF_WALLTIME equ 1 Set to 1 for a software wall time clock ( defs.d):00013 ( defs.d):00014 * Module CRC and header parity checks are useful for integrity, but slows down loading. 0001 ( defs.d):00015 _FF_MODCHECK equ 1 Set to 1 for module header and CRC checking ( defs.d):00016 ( defs.d):00017 * Unified I/O adds a standard device interface at the expense of more memory. 0001 ( defs.d):00018 _FF_UNIFIED_IO equ 1 Set to 1 for unified I/O ( defs.d):00019 ( defs.d):00020 * Booting from an external storage device can bring in additional functionality. 0001 ( defs.d):00021 _FF_BOOTING equ 1 Set to 1 for bootfile loading ( defs.d):00022 ( defs.d):00023 * User IDs are useful for multi-user configurations. 0001 ( defs.d):00024 _FF_ID equ 1 Set to 1 to support user IDs ( defs.d):00025 ( defs.d):00026 * Without this system call, all processes run at priority 128. 0001 ( defs.d):00027 _FF_SPRIOR equ 1 Set to 1 to support setting process priority ( defs.d):00028 ( defs.d):00029 * Setting the software interrupt vector is not typically needed. 0001 ( defs.d):00030 _FF_SSWI equ 1 Set to 1 to support setting software interrupt vector ( defs.d):00031 ( defs.d):00032 * TurbOS system definitions ( defs.d):00033 use turbos.d ( turbos.d):00001 ******************************************************************************* ( turbos.d):00002 * TurbOS ( turbos.d):00003 ******************************************************************************* ( turbos.d):00004 * See LICENSE.txt for licensing information. ( turbos.d):00005 ******************************************************************************* ( turbos.d):00006 * ( turbos.d):00007 * Edt/Rev YYYY/MM/DD Modified by ( turbos.d):00008 * Comment ( turbos.d):00009 * ---------------------------------------------------------------------------- ( turbos.d):00010 * 2023/08/11 Boisy Pitre ( turbos.d):00011 * Initial creation. ( turbos.d):00012 * ( turbos.d):00013 ******************************************************************************* ( turbos.d):00014 ( turbos.d):00015 ifne TURBOS.D-1 ( turbos.d):00016 0001 ( turbos.d):00017 TURBOS.D set 1 ( turbos.d):00018 ( turbos.d):00019 nam turbos.d ( turbos.d):00020 ttl TurbOS system definitions ( turbos.d):00021 ( turbos.d):00022 * Common definitions 0001 ( turbos.d):00023 true equ 1 0000 ( turbos.d):00024 false equ 0 ( turbos.d):00025 ( turbos.d):00026 pag ( turbos.d):00027 ***************************************** ( turbos.d):00028 * System service request code definitions ( turbos.d):00029 * ( turbos.d):00030 org 0 ( turbos.d):00031 * User and system state calls 0000 ( turbos.d):00032 F$Link rmb 1 link to module 0001 ( turbos.d):00033 F$Load rmb 1 load module from file 0002 ( turbos.d):00034 F$UnLink rmb 1 unlink module 0003 ( turbos.d):00035 F$Fork rmb 1 start new process 0004 ( turbos.d):00036 F$Wait rmb 1 wait for child process to die 0005 ( turbos.d):00037 F$Chain rmb 1 chain process to new module 0006 ( turbos.d):00038 F$Exit rmb 1 terminate process 0007 ( turbos.d):00039 F$Mem rmb 1 set memory size 0008 ( turbos.d):00040 F$Send rmb 1 send signal to process 0009 ( turbos.d):00041 F$Icpt rmb 1 set signal intercept 000A ( turbos.d):00042 F$Sleep rmb 1 suspend process 000B ( turbos.d):00043 F$ID rmb 1 return process ID 000C ( turbos.d):00044 F$SPrior rmb 1 set process priority 000D ( turbos.d):00045 F$SSWI rmb 1 set software interrupt 000E ( turbos.d):00046 F$PErr rmb 1 print Error 000F ( turbos.d):00047 F$PrsNam rmb 1 parse pathlist name 0010 ( turbos.d):00048 F$CmpNam rmb 1 compare two names 0011 ( turbos.d):00049 F$SchBit rmb 1 search bit map 0012 ( turbos.d):00050 F$AllBit rmb 1 allocate in bit map 0013 ( turbos.d):00051 F$DelBit rmb 1 deallocate in bit map 0014 ( turbos.d):00052 F$Time rmb 1 get current time 0015 ( turbos.d):00053 F$STime rmb 1 set current time 0016 ( turbos.d):00054 F$CRC rmb 1 generate CRC ( turbos.d):00055 ( turbos.d):00056 org $27 beginning of system reserved calls ( turbos.d):00057 * System state (privileged) calls 0027 ( turbos.d):00058 F$VIRQ rmb 1 install/delete virtual IRQ 0028 ( turbos.d):00059 F$SRqMem rmb 1 system memory request 0029 ( turbos.d):00060 F$SRtMem rmb 1 system memory return 002A ( turbos.d):00061 F$IRQ rmb 1 enter IRQ polling table 002B ( turbos.d):00062 F$IOQu rmb 1 enter I/O queue 002C ( turbos.d):00063 F$AProc rmb 1 enter active process queue 002D ( turbos.d):00064 F$NProc rmb 1 start next process 002E ( turbos.d):00065 F$VModul rmb 1 validate module 002F ( turbos.d):00066 F$Find64 rmb 1 find process/path descriptor 0030 ( turbos.d):00067 F$All64 rmb 1 allocate process/path descriptor 0031 ( turbos.d):00068 F$Ret64 rmb 1 return process/path descriptor 0032 ( turbos.d):00069 F$SSvc rmb 1 service request table initialization 0033 ( turbos.d):00070 F$IODel rmb 1 delete I/O module ( turbos.d):00071 ( turbos.d):00072 * ( turbos.d):00073 * System calls $70 through $7F are reserved for user definitions ( turbos.d):00074 * ( turbos.d):00075 org $70 0070 ( turbos.d):00076 rmb 16 reserved for user definition ( turbos.d):00077 ( turbos.d):00078 pag ( turbos.d):00079 ************************************** ( turbos.d):00080 * I/O service request code definitions ( turbos.d):00081 * ( turbos.d):00082 org $80 0080 ( turbos.d):00083 I$Attach rmb 1 attach I/O device 0081 ( turbos.d):00084 I$Detach rmb 1 detach I/O device 0082 ( turbos.d):00085 I$Dup rmb 1 duplicate path 0083 ( turbos.d):00086 I$Create rmb 1 create new file 0084 ( turbos.d):00087 I$Open rmb 1 open existing file 0085 ( turbos.d):00088 I$MakDir rmb 1 make directory file 0086 ( turbos.d):00089 I$ChgDir rmb 1 change default directory 0087 ( turbos.d):00090 I$Delete rmb 1 delete file 0088 ( turbos.d):00091 I$Seek rmb 1 change current position 0089 ( turbos.d):00092 I$Read rmb 1 read data 008A ( turbos.d):00093 I$Write rmb 1 write data 008B ( turbos.d):00094 I$ReadLn rmb 1 read line of ASCII data 008C ( turbos.d):00095 I$WritLn rmb 1 write line of ASCII data 008D ( turbos.d):00096 I$GetStt rmb 1 get path status 008E ( turbos.d):00097 I$SetStt rmb 1 set path status 008F ( turbos.d):00098 I$Close rmb 1 close path 0090 ( turbos.d):00099 I$DeletX rmb 1 delete from current exec dir ( turbos.d):00100 ( turbos.d):00101 ******************* ( turbos.d):00102 * File access modes ( turbos.d):00103 * 0001 ( turbos.d):00104 READ. equ %00000001 0002 ( turbos.d):00105 WRITE. equ %00000010 0003 ( turbos.d):00106 UPDAT. equ READ.+WRITE. 0004 ( turbos.d):00107 EXEC. equ %00000100 0008 ( turbos.d):00108 PREAD. equ %00001000 0010 ( turbos.d):00109 PWRIT. equ %00010000 0020 ( turbos.d):00110 PEXEC. equ %00100000 0040 ( turbos.d):00111 SHARE. equ %01000000 0080 ( turbos.d):00112 DIR. equ %10000000 0020 ( turbos.d):00113 ISIZ. equ %00100000 ( turbos.d):00114 ( turbos.d):00115 ************** ( turbos.d):00116 * Signal codes ( turbos.d):00117 * ( turbos.d):00118 org 0 0000 ( turbos.d):00119 S$Kill rmb 1 non-interceptable abort 0001 ( turbos.d):00120 S$Wake rmb 1 wake-up sleeping process 0002 ( turbos.d):00121 S$Abort rmb 1 keyboard abort 0003 ( turbos.d):00122 S$Intrpt rmb 1 keyboard interrupt ( turbos.d):00123 ( turbos.d):00124 pag ( turbos.d):00125 ********************************** ( turbos.d):00126 * Status codes for GetStat/SetStat ( turbos.d):00127 * ( turbos.d):00128 org 0 0000 ( turbos.d):00129 SS.Opt rmb 1 read/Write path descriptor options 0001 ( turbos.d):00130 SS.Ready rmb 1 check for device ready 0002 ( turbos.d):00131 SS.Size rmb 1 read/write file size 0003 ( turbos.d):00132 SS.Reset rmb 1 device restore 0004 ( turbos.d):00133 rmb 1 0005 ( turbos.d):00134 SS.Pos rmb 1 get file's current position 0006 ( turbos.d):00135 SS.EOF rmb 1 test for end of file 0007 ( turbos.d):00136 SS.Link rmb 1 link to status routines 0008 ( turbos.d):00137 SS.ULink rmb 1 unlink status routines 0009 ( turbos.d):00138 rmb 1 000A ( turbos.d):00139 SS.Frz rmb 1 freeze DD. information 000B ( turbos.d):00140 SS.SPT rmb 1 set DD.TKS to given value 000C ( turbos.d):00141 rmb 1 000D ( turbos.d):00142 SS.DCmd rmb 1 send direct command to disk 000E ( turbos.d):00143 SS.DevNm rmb 1 return device name (32-bytes at [X]) 000F ( turbos.d):00144 SS.FD rmb 1 return file descriptor (Y-bytes at [X]) 0010 ( turbos.d):00145 SS.Ticks rmb 1 set lockout honor duration 0011 ( turbos.d):00146 SS.Lock rmb 1 lock/release record 0012 ( turbos.d):00147 rmb 1 0013 ( turbos.d):00148 rmb 1 0014 ( turbos.d):00149 SS.BlkRd rmb 1 block read 0015 ( turbos.d):00150 SS.BlkWr rmb 1 block write 0016 ( turbos.d):00151 SS.Reten rmb 1 retension cycle 0017 ( turbos.d):00152 SS.WFM rmb 1 write file mark 0018 ( turbos.d):00153 SS.RFM rmb 1 read past file mark 0019 ( turbos.d):00154 SS.ELog rmb 1 read error log 001A ( turbos.d):00155 SS.SSig rmb 1 send signal on data ready 001B ( turbos.d):00156 SS.Relea rmb 1 release device 001C ( turbos.d):00157 rmb 1 001D ( turbos.d):00158 rmb 1 001E ( turbos.d):00159 SS.RsBit rmb 1 reserve bitmap sector (do not allocate in) LSB(X)=sct# 001F ( turbos.d):00160 rmb 1 reserved 0020 ( turbos.d):00161 rmb 1 0021 ( turbos.d):00162 rmb 3 0024 ( turbos.d):00163 rmb 1 0025 ( turbos.d):00164 rmb 1 0026 ( turbos.d):00165 rmb 1 0027 ( turbos.d):00166 rmb 1 0028 ( turbos.d):00167 SS.ComSt rmb 1 Getstat/SetStat for baud/parity 0029 ( turbos.d):00168 SS.Open rmb 1 SetStat to tell driver a path was opened 002A ( turbos.d):00169 SS.Close rmb 1 SetStat to tell driver a path was closed 002B ( turbos.d):00170 SS.HngUp rmb 1 SetStat to tell driver to hangup phone 002C ( turbos.d):00171 SS.FSig rmb 1 new signal for temp locked files 002D ( turbos.d):00172 rmb 19 ( turbos.d):00173 ( turbos.d):00174 org $A0 00A0 ( turbos.d):00175 rmb 1 00A1 ( turbos.d):00176 SS.Fill rmb 1 enable command-line history erase (scf) ( turbos.d):00177 ttl Direct Page Definitions ( turbos.d):00178 pag ( turbos.d):00179 ( turbos.d):00180 ********************************** ( turbos.d):00181 * Direct page variable definitions ( turbos.d):00182 * ( turbos.d):00183 org $00 ( turbos.d):00184 org $20 0020 ( turbos.d):00185 D.FMBM rmb 4 free memory bit map pointers 0024 ( turbos.d):00186 D.MLIM rmb 2 upper RAM memory limit 0026 ( turbos.d):00187 D.ModDir rmb 4 module directory pointers (start and end) 002A ( turbos.d):00188 D.Init rmb 2 configuration module base address 002C ( turbos.d):00189 D.SWI3 rmb 2 SWI3 vector 002E ( turbos.d):00190 D.SWI2 rmb 2 SWI2 vector 0030 ( turbos.d):00191 D.FIRQ rmb 2 FIRQ vector 0032 ( turbos.d):00192 D.IRQ rmb 2 IRQ vector 0034 ( turbos.d):00193 D.SWI rmb 2 SWI vector 0036 ( turbos.d):00194 D.NMI rmb 2 NMI vector 0038 ( turbos.d):00195 D.SvcIRQ rmb 2 interrupt service entry 003A ( turbos.d):00196 D.Poll rmb 2 interrupt polling routine 003C ( turbos.d):00197 D.UsrIRQ rmb 2 user interrupt routine 003E ( turbos.d):00198 D.SysIRQ rmb 2 system interrupt routine 0040 ( turbos.d):00199 D.UsrSvc rmb 2 user service request routine 0042 ( turbos.d):00200 D.SysSvc rmb 2 system service request routine 0044 ( turbos.d):00201 D.UsrDis rmb 2 user service request dispatch table 0046 ( turbos.d):00202 D.SysDis rmb 2 system service reuest dispatch table 0048 ( turbos.d):00203 D.Slice rmb 1 process time slice count 0049 ( turbos.d):00204 D.PrcDBT rmb 2 process descriptor block table 004B ( turbos.d):00205 D.Proc rmb 2 process descriptor address 004D ( turbos.d):00206 D.AProcQ rmb 2 active process queue 004F ( turbos.d):00207 D.WProcQ rmb 2 waiting process queue 0051 ( turbos.d):00208 D.SProcQ rmb 2 sleeping process queue 0053 ( turbos.d):00209 D.Time equ . time 0053 ( turbos.d):00210 D.Year rmb 1 current year 0054 ( turbos.d):00211 D.Month rmb 1 current month 0055 ( turbos.d):00212 D.Day rmb 1 current da 0056 ( turbos.d):00213 D.Hour rmb 1 current hour 0057 ( turbos.d):00214 D.Min rmb 1 current minute 0058 ( turbos.d):00215 D.Sec rmb 1 current second 0059 ( turbos.d):00216 D.Ticks rmb 4 number of ticks since boot 005D ( turbos.d):00217 D.Tick rmb 1 current tick 005E ( turbos.d):00218 D.TSec rmb 1 ticks per second 005F ( turbos.d):00219 D.TSlice rmb 1 ticks per time-slice 0060 ( turbos.d):00220 D.IOML rmb 2 I/O manager free memory low bound 0062 ( turbos.d):00221 D.IOMH rmb 2 I/O manager free memory hi bound 0064 ( turbos.d):00222 D.DevTbl rmb 2 device driver table address 0066 ( turbos.d):00223 D.PolTbl rmb 2 interrupt polling table address 0068 ( turbos.d):00224 D.PthDBT rmb 2 path descriptor block table addrress 006A ( turbos.d):00225 D.BTLO rmb 2 bootstrap low address 006C ( turbos.d):00226 D.BTHI rmb 2 bootstrap hi address 006E ( turbos.d):00227 D.Clock rmb 2 address of clock tick routine 0070 ( turbos.d):00228 D.Boot rmb 1 bootstrap attempted flag 0071 ( turbos.d):00229 D.URtoSs rmb 2 address of user to system routine (VIRQ) 0073 ( turbos.d):00230 D.VIRQTable rmb 2 pointer to virtual IRQ table 0075 ( turbos.d):00231 D.CRC rmb 1 CRC checking mode flag ( turbos.d):00232 ( turbos.d):00233 org $100 0100 ( turbos.d):00234 D.XSWI3 rmb 3 0103 ( turbos.d):00235 D.XSWI2 rmb 3 0106 ( turbos.d):00236 D.XSWI rmb 3 0109 ( turbos.d):00237 D.XNMI rmb 3 010C ( turbos.d):00238 D.XIRQ rmb 3 010F ( turbos.d):00239 D.XFIRQ rmb 3 ( turbos.d):00240 ( turbos.d):00241 * Table Sizes 0020 ( turbos.d):00242 BMAPSZ equ 65536/256/8 memory allocation bitmap table size 0002 ( turbos.d):00243 SVCTNM equ 2 number of service request tables 006E ( turbos.d):00244 SVCTSZ equ (256-BMAPSZ)/SVCTNM-2 service request table size ( turbos.d):00245 ( turbos.d):00246 ttl Structure Formats ( turbos.d):00247 pag ( turbos.d):00248 ************************************ ( turbos.d):00249 * Module directory entry definitions ( turbos.d):00250 * ( turbos.d):00251 org 0 0000 ( turbos.d):00252 MD$MPtr rmb 2 module pointer 0002 ( turbos.d):00253 MD$Link rmb 1 module link count 0003 ( turbos.d):00254 rmb 1 0004 ( turbos.d):00255 MD$ESize equ . module directory entry size ( turbos.d):00256 ( turbos.d):00257 ************************************ ( turbos.d):00258 * Module definitions ( turbos.d):00259 * ( turbos.d):00260 * Universal module offsets ( turbos.d):00261 * ( turbos.d):00262 org 0 0000 ( turbos.d):00263 M$ID rmb 2 ID code 0002 ( turbos.d):00264 M$Size rmb 2 module size 0004 ( turbos.d):00265 M$Name rmb 2 module name 0006 ( turbos.d):00266 M$Type rmb 1 type / language 0007 ( turbos.d):00267 M$Revs rmb 1 attributes / revision level 0008 ( turbos.d):00268 M$Parity rmb 1 header parity 0009 ( turbos.d):00269 M$IDSize equ . Mmdule ID size ( turbos.d):00270 ( turbos.d):00271 * ( turbos.d):00272 * Type-dependent module offsets ( turbos.d):00273 * ( turbos.d):00274 * System, file manager, device driver, program module ( turbos.d):00275 * 0009 ( turbos.d):00276 M$Exec rmb 2 execution entry offset ( turbos.d):00277 * ( turbos.d):00278 * Device driver, program module ( turbos.d):00279 * 000B ( turbos.d):00280 M$Mem rmb 2 stack requirement ( turbos.d):00281 * ( turbos.d):00282 * Device driver, device descriptor module ( turbos.d):00283 * 000D ( turbos.d):00284 M$Mode rmb 1 device driver mode capabilities ( turbos.d):00285 * ( turbos.d):00286 * Device descriptor module ( turbos.d):00287 * ( turbos.d):00288 org M$IDSize 0009 ( turbos.d):00289 M$FMgr rmb 2 file manager name offset 000B ( turbos.d):00290 M$PDev rmb 2 device driver name offset 000D ( turbos.d):00291 rmb 1 M$Mode (defined above) 000E ( turbos.d):00292 M$Port rmb 3 port address 0011 ( turbos.d):00293 M$Opt rmb 1 device default options 0012 ( turbos.d):00294 M$DTyp rmb 1 device type 0012 ( turbos.d):00295 IT.DTP equ M$DTyp descriptor type offset ( turbos.d):00296 ( turbos.d):00297 * ( turbos.d):00298 * Configuration module entry offsets ( turbos.d):00299 * ( turbos.d):00300 org M$IDSize 0009 ( turbos.d):00301 CM$MaxMem rmb 3 maximum free memory 000C ( turbos.d):00302 CM$PollCnt rmb 1 entries in interrupt polling table 000D ( turbos.d):00303 CM$DevCnt rmb 1 entries in device table 000E ( turbos.d):00304 CM$TickMod rmb 2 tick generator module name 0010 ( turbos.d):00305 CM$GoMod rmb 2 startup module name ( turbos.d):00306 ifne _FF_UNIFIED_IO 0012 ( turbos.d):00307 CM$StoreMod rmb 2 initial storage device name 0014 ( turbos.d):00308 CM$ConsoleMod rmb 2 initial console device name ( turbos.d):00309 endc ( turbos.d):00310 ifne _FF_BOOTING 0016 ( turbos.d):00311 CM$BootMod rmb 2 boot module name ( turbos.d):00312 endc 0018 ( turbos.d):00313 CM$OSLevel rmb 1 operating system level 0019 ( turbos.d):00314 CM$OSVer rmb 1 operating system version 001A ( turbos.d):00315 CM$OSMajor rmb 1 operating system major 001B ( turbos.d):00316 CM$OSMinor rmb 1 operating system minor 001C ( turbos.d):00317 CM$Feature1 rmb 1 feature byte 1 001D ( turbos.d):00318 CM$Feature2 rmb 1 feature byte 2 001E ( turbos.d):00319 rmb 4 reserved for future use ( turbos.d):00320 ( turbos.d):00321 * Feature1 byte definitions 0001 ( turbos.d):00322 CRCOn equ %00000001 CRC checking on 0000 ( turbos.d):00323 CRCOff equ %00000000 CRC checking off ( turbos.d):00324 ( turbos.d):00325 pag ( turbos.d):00326 ************************** ( turbos.d):00327 * Module field definitions ( turbos.d):00328 * ( turbos.d):00329 * ID field - first two bytes of a module ( turbos.d):00330 * 0087 ( turbos.d):00331 M$ID1 equ $87 module ID code byte one 00CD ( turbos.d):00332 M$ID2 equ $CD module ID code byte two 87CD ( turbos.d):00333 M$ID12 equ M$ID1*256+M$ID2 ( turbos.d):00334 ( turbos.d):00335 * ( turbos.d):00336 * Module type/language field masks ( turbos.d):00337 * 00F0 ( turbos.d):00338 TypeMask equ %11110000 type field 000F ( turbos.d):00339 LangMask equ %00001111 language field ( turbos.d):00340 ( turbos.d):00341 * ( turbos.d):00342 * Module type values ( turbos.d):00343 * 00F0 ( turbos.d):00344 Devic equ $F0 device descriptor module 00E0 ( turbos.d):00345 Drivr equ $E0 physical device driver 00D0 ( turbos.d):00346 FlMgr equ $D0 file manager 00C0 ( turbos.d):00347 Systm equ $C0 system module 0040 ( turbos.d):00348 Data equ $40 data module 0020 ( turbos.d):00349 Sbrtn equ $20 subroutine module 0010 ( turbos.d):00350 Prgrm equ $10 program module ( turbos.d):00351 ( turbos.d):00352 * ( turbos.d):00353 * Module language values ( turbos.d):00354 * 0001 ( turbos.d):00355 Objct equ 1 object code module ( turbos.d):00356 ( turbos.d):00357 * ( turbos.d):00358 * Module attributes / revision byte ( turbos.d):00359 * ( turbos.d):00360 * Field masks ( turbos.d):00361 * 00F0 ( turbos.d):00362 AttrMask equ %11110000 attributes field 000F ( turbos.d):00363 RevsMask equ %00001111 revision level field ( turbos.d):00364 ( turbos.d):00365 * ( turbos.d):00366 * Attribute flags ( turbos.d):00367 * 0080 ( turbos.d):00368 ReEnt equ %10000000 re-entrant module ( turbos.d):00369 ( turbos.d):00370 ******************** ( turbos.d):00371 * Device type values ( turbos.d):00372 * ( turbos.d):00373 * These values define various classes of devices, which are ( turbos.d):00374 * managed by a file manager module. The device type is embedded ( turbos.d):00375 * in a device descriptor. ( turbos.d):00376 * 0000 ( turbos.d):00377 DT.SCF equ 0 sequential character file manager 0001 ( turbos.d):00378 DT.RBF equ 1 random block file manager 0002 ( turbos.d):00379 DT.Pipe equ 2 pipe file manager ( turbos.d):00380 ( turbos.d):00381 ********************* ( turbos.d):00382 * CRC result constant ( turbos.d):00383 * 0080 ( turbos.d):00384 CRCCon1 equ $80 0FE3 ( turbos.d):00385 CRCCon23 equ $0FE3 ( turbos.d):00386 ( turbos.d):00387 ttl Process Information ( turbos.d):00388 pag ( turbos.d):00389 ******************************** ( turbos.d):00390 * Process descriptor definitions ( turbos.d):00391 * 000C ( turbos.d):00392 DefIOSiz equ 12 0010 ( turbos.d):00393 NumPaths equ 16 number of local paths ( turbos.d):00394 ( turbos.d):00395 org 0 0000 ( turbos.d):00396 P$ID rmb 1 process ID 0001 ( turbos.d):00397 P$PID rmb 1 parent's ID 0002 ( turbos.d):00398 P$SID rmb 1 sibling's ID 0003 ( turbos.d):00399 P$CID rmb 1 child's ID 0004 ( turbos.d):00400 P$SP rmb 2 stack pointer 0006 ( turbos.d):00401 P$CHAP rmb 1 process chapter number 0007 ( turbos.d):00402 P$ADDR rmb 1 user address beginning page number 0008 ( turbos.d):00403 P$PagCnt rmb 1 memory page count 0009 ( turbos.d):00404 P$User rmb 2 user index 000B ( turbos.d):00405 P$Prior rmb 1 priority 000C ( turbos.d):00406 P$Age rmb 1 age 000D ( turbos.d):00407 P$State rmb 1 status 000E ( turbos.d):00408 P$Queue rmb 2 queue link (process pointer) 0010 ( turbos.d):00409 P$IOQP rmb 1 previous I/O queue link (process ID) 0011 ( turbos.d):00410 P$IOQN rmb 1 next I/O queue link (process ID) 0012 ( turbos.d):00411 P$PModul rmb 2 primary module 0014 ( turbos.d):00412 P$SWI rmb 2 SWI entry point 0016 ( turbos.d):00413 P$SWI2 rmb 2 SWI2 entry point 0018 ( turbos.d):00414 P$SWI3 rmb 2 SWI3 entry point 001A ( turbos.d):00415 P$DIO rmb DefIOSiz default I/O pointers 0026 ( turbos.d):00416 P$PATH rmb NumPaths I/O path table 0036 ( turbos.d):00417 P$Signal rmb 1 signal code 0037 ( turbos.d):00418 P$SigVec rmb 2 signal intercept vector 0039 ( turbos.d):00419 P$SigDat rmb 2 signal intercept data address 003B ( turbos.d):00420 P$NIO rmb 4 003F ( turbos.d):00421 rmb $40-. unused 0040 ( turbos.d):00422 P$Size equ . size of process descriptor ( turbos.d):00423 ( turbos.d):00424 * ( turbos.d):00425 * Process state flags ( turbos.d):00426 * 0080 ( turbos.d):00427 SysState equ %10000000 0040 ( turbos.d):00428 TimSleep equ %01000000 0020 ( turbos.d):00429 TimOut equ %00100000 0010 ( turbos.d):00430 ImgChg equ %00010000 0002 ( turbos.d):00431 Condem equ %00000010 0001 ( turbos.d):00432 Dead equ %00000001 ( turbos.d):00433 ( turbos.d):00434 ttl I/O Definitions ( turbos.d):00435 pag ( turbos.d):00436 ************************* ( turbos.d):00437 * Path descriptor offsets ( turbos.d):00438 * ( turbos.d):00439 org 0 0000 ( turbos.d):00440 PD.PD rmb 1 path number 0001 ( turbos.d):00441 PD.MOD rmb 1 mode (read/write/update) 0002 ( turbos.d):00442 PD.CNT rmb 1 number of open images 0003 ( turbos.d):00443 PD.DEV rmb 2 device table entry address 0005 ( turbos.d):00444 PD.CPR rmb 1 current process 0006 ( turbos.d):00445 PD.RGS rmb 2 caller's register stack 0008 ( turbos.d):00446 PD.BUF rmb 2 buffer address 000A ( turbos.d):00447 PD.FST rmb 32-. file manager's storage 0020 ( turbos.d):00448 PD.OPT equ . path descriptor options 0020 ( turbos.d):00449 PD.DTP rmb 1 device type 0021 ( turbos.d):00450 rmb 64-. path options end 0040 ( turbos.d):00451 PDSIZE equ . ( turbos.d):00452 ( turbos.d):00453 * ( turbos.d):00454 * Pathlist special symbols ( turbos.d):00455 * 002F ( turbos.d):00456 PDELIM equ '/ pathlist name separator 002E ( turbos.d):00457 PDIR equ '. directory 0040 ( turbos.d):00458 PENTIR equ '@ entire device ( turbos.d):00459 ( turbos.d):00460 pag ( turbos.d):00461 **************************** ( turbos.d):00462 * File manager entry offsets ( turbos.d):00463 * ( turbos.d):00464 org 0 0000 ( turbos.d):00465 FMCREA rmb 3 create (open new) file 0003 ( turbos.d):00466 FMOPEN rmb 3 open file 0006 ( turbos.d):00467 FMMDIR rmb 3 make directory 0009 ( turbos.d):00468 FMCDIR rmb 3 change directory 000C ( turbos.d):00469 FMDLET rmb 3 delete file 000F ( turbos.d):00470 FMSEEK rmb 3 position file 0012 ( turbos.d):00471 FMREAD rmb 3 read from file 0015 ( turbos.d):00472 FMWRIT rmb 3 write to file 0018 ( turbos.d):00473 FMRDLN rmb 3 read line 001B ( turbos.d):00474 FMWRLN rmb 3 write line 001E ( turbos.d):00475 FMGSTA rmb 3 get file status 0021 ( turbos.d):00476 FMSSTA rmb 3 set file status 0024 ( turbos.d):00477 FMCLOS rmb 3 close file ( turbos.d):00478 ( turbos.d):00479 ***************************** ( turbos.d):00480 * Device driver entry offsets ( turbos.d):00481 * ( turbos.d):00482 org 0 0000 ( turbos.d):00483 D$INIT rmb 3 device initialization 0003 ( turbos.d):00484 D$READ rmb 3 read from device 0006 ( turbos.d):00485 D$WRIT rmb 3 write to device 0009 ( turbos.d):00486 D$GSTA rmb 3 get device status 000C ( turbos.d):00487 D$PSTA rmb 3 put device status 000F ( turbos.d):00488 D$TERM rmb 3 device termination ( turbos.d):00489 ( turbos.d):00490 ********************* ( turbos.d):00491 * Device table format ( turbos.d):00492 * ( turbos.d):00493 org 0 0000 ( turbos.d):00494 V$DRIV rmb 2 device driver module 0002 ( turbos.d):00495 V$STAT rmb 2 device driver static storage 0004 ( turbos.d):00496 V$DESC rmb 2 device descriptor module 0006 ( turbos.d):00497 V$FMGR rmb 2 file manager module 0008 ( turbos.d):00498 V$USRS rmb 1 use count 0009 ( turbos.d):00499 DEVSIZ equ . ( turbos.d):00500 ( turbos.d):00501 ******************************* ( turbos.d):00502 * Device static storage offsets ( turbos.d):00503 * ( turbos.d):00504 org 0 0000 ( turbos.d):00505 V.PAGE rmb 1 port extended address 0001 ( turbos.d):00506 V.PORT rmb 2 device 'base' port address 0003 ( turbos.d):00507 V.LPRC rmb 1 last active process ID 0004 ( turbos.d):00508 V.BUSY rmb 1 active process ID (0=not busy) 0005 ( turbos.d):00509 V.WAKE rmb 1 active process descriptor if driver MUST wake-up 0006 ( turbos.d):00510 V.USER equ . driver allocation origin ( turbos.d):00511 ( turbos.d):00512 ******************************** ( turbos.d):00513 * Interrupt polling table format ( turbos.d):00514 * ( turbos.d):00515 org 0 0000 ( turbos.d):00516 Q$Poll rmb 2 absolute polling address 0002 ( turbos.d):00517 Q$Flip rmb 1 flip (EOR) byte; normally zero 0003 ( turbos.d):00518 Q$Mask rmb 1 polling mask (after flip) 0004 ( turbos.d):00519 Q$Serv rmb 2 absolute service routine Address 0006 ( turbos.d):00520 Q$Stat rmb 2 static storage address 0008 ( turbos.d):00521 Q$Prty rmb 1 priority (low numbers=top priority) 0009 ( turbos.d):00522 POLSIZ equ . ( turbos.d):00523 ( turbos.d):00524 ******************** ( turbos.d):00525 * VIRQ packet format ( turbos.d):00526 * ( turbos.d):00527 org 0 0000 ( turbos.d):00528 Vi.Cnt rmb 2 count down counter 0002 ( turbos.d):00529 Vi.Rst rmb 2 reset value for counter 0004 ( turbos.d):00530 Vi.Stat rmb 1 status byte 0005 ( turbos.d):00531 Vi.PkSz equ . ( turbos.d):00532 0001 ( turbos.d):00533 Vi.IFlag equ %00000001 status byte virq flag ( turbos.d):00534 ( turbos.d):00535 pag ( turbos.d):00536 ************************************* ( turbos.d):00537 * Machine characteristics definitions ( turbos.d):00538 * 0000 ( turbos.d):00539 R$CC equ 0 condition codes register 0001 ( turbos.d):00540 R$A equ 1 A accumulator 0002 ( turbos.d):00541 R$B equ 2 B accumulator 0001 ( turbos.d):00542 R$D equ R$A combined A:B accumulator 0003 ( turbos.d):00543 R$DP equ 3 direct page register 0004 ( turbos.d):00544 R$X equ 4 X index register 0006 ( turbos.d):00545 R$Y equ 6 Y index register 0008 ( turbos.d):00546 R$U equ 8 user stack register 000A ( turbos.d):00547 R$PC equ 10 program counter register 000C ( turbos.d):00548 R$Size equ 12 total register package size ( turbos.d):00549 0080 ( turbos.d):00550 Entire equ %10000000 full register stack flag 0040 ( turbos.d):00551 FIRQMask equ %01000000 fast interrupt mask bit 0020 ( turbos.d):00552 HalfCrry equ %00100000 half carry flag 0010 ( turbos.d):00553 IRQMask equ %00010000 interrupt mask bit 0008 ( turbos.d):00554 Negative equ %00001000 negative flag 0004 ( turbos.d):00555 Zero equ %00000100 zero flag 0002 ( turbos.d):00556 TwosOvfl equ %00000010 two's complement overflow flag 0001 ( turbos.d):00557 Carry equ %00000001 carry bit 0050 ( turbos.d):00558 IntMasks equ IRQMask+FIRQMask 0080 ( turbos.d):00559 Sign equ %10000000 sign bit ( turbos.d):00560 ( turbos.d):00561 ttl Error code definitions ( turbos.d):00562 pag ( turbos.d):00563 ************************ ( turbos.d):00564 * Error code definitions ( turbos.d):00565 * ( turbos.d):00566 org 200 00C8 ( turbos.d):00567 E$PthFul rmb 1 path table full 00C9 ( turbos.d):00568 E$BPNum rmb 1 bad path number 00CA ( turbos.d):00569 E$Poll rmb 1 polling table Full 00CB ( turbos.d):00570 E$BMode rmb 1 bad Mode 00CC ( turbos.d):00571 E$DevOvf rmb 1 device table overflow 00CD ( turbos.d):00572 E$BMID rmb 1 bad module ID 00CE ( turbos.d):00573 E$DirFul rmb 1 module directory full 00CF ( turbos.d):00574 E$MemFul rmb 1 process memory full 00D0 ( turbos.d):00575 E$UnkSvc rmb 1 unknown service code 00D1 ( turbos.d):00576 E$ModBsy rmb 1 module busy 00D2 ( turbos.d):00577 E$BPAddr rmb 1 bad page address 00D3 ( turbos.d):00578 E$EOF rmb 1 end of file 00D4 ( turbos.d):00579 rmb 1 00D5 ( turbos.d):00580 E$NES rmb 1 non-existent segment 00D6 ( turbos.d):00581 E$FNA rmb 1 file not accesible 00D7 ( turbos.d):00582 E$BPNam rmb 1 bad path name 00D8 ( turbos.d):00583 E$PNNF rmb 1 path name Not Found 00D9 ( turbos.d):00584 E$SLF rmb 1 segment list full 00DA ( turbos.d):00585 E$CEF rmb 1 creating existing file 00DB ( turbos.d):00586 E$IBA rmb 1 illegal block address 00DC ( turbos.d):00587 E$HangUp rmb 1 carrier detect lost 00DD ( turbos.d):00588 E$MNF rmb 1 module not found 00DE ( turbos.d):00589 rmb 1 00DF ( turbos.d):00590 E$DelSP rmb 1 deleting stack pointer memory 00E0 ( turbos.d):00591 E$IPrcID rmb 1 illegal process ID 00E0 ( turbos.d):00592 E$BPrcID equ E$IPrcID bad process ID 00E1 ( turbos.d):00593 rmb 1 00E2 ( turbos.d):00594 E$NoChld rmb 1 no children 00E3 ( turbos.d):00595 E$ISWI rmb 1 illegal SWI code 00E4 ( turbos.d):00596 E$PrcAbt rmb 1 process aborted 00E5 ( turbos.d):00597 E$PrcFul rmb 1 process table full 00E6 ( turbos.d):00598 E$IForkP rmb 1 illegal fork parameter 00E7 ( turbos.d):00599 E$KwnMod rmb 1 known module 00E8 ( turbos.d):00600 E$BMCRC rmb 1 bad module CRC 00E9 ( turbos.d):00601 E$USigP rmb 1 unprocessed signal pending 00EA ( turbos.d):00602 E$NEMod rmb 1 non-existent module 00EB ( turbos.d):00603 E$BNam rmb 1 bad name 00EC ( turbos.d):00604 E$BMHP rmb 1 bad module header parity 00ED ( turbos.d):00605 E$NoRAM rmb 1 no system RAM available 00EE ( turbos.d):00606 E$DNE rmb 1 directory not empty 00EF ( turbos.d):00607 E$NoTask rmb 1 no available task number ( turbos.d):00608 rmb $F0-. reserved 00F0 ( turbos.d):00609 E$Unit rmb 1 illegal media unit 00F1 ( turbos.d):00610 E$Sect rmb 1 bad sector number 00F2 ( turbos.d):00611 E$WP rmb 1 write protect 00F3 ( turbos.d):00612 E$CRC rmb 1 bad checksum 00F4 ( turbos.d):00613 E$Read rmb 1 read error 00F5 ( turbos.d):00614 E$Write rmb 1 write error 00F6 ( turbos.d):00615 E$NotRdy rmb 1 device not ready 00F7 ( turbos.d):00616 E$Seek rmb 1 seek error 00F8 ( turbos.d):00617 E$Full rmb 1 media full 00F9 ( turbos.d):00618 E$BTyp rmb 1 bad type (incompatible) media 00FA ( turbos.d):00619 E$DevBsy rmb 1 device busy 00FB ( turbos.d):00620 E$DIDC rmb 1 media ID change 00FC ( turbos.d):00621 E$Lock rmb 1 record is busy (locked out) 00FD ( turbos.d):00622 E$Share rmb 1 non-sharable file busy 00FE ( turbos.d):00623 E$DeadLk rmb 1 I/O deadlock error ( turbos.d):00624 ( turbos.d):00625 * Character definitions 0020 ( turbos.d):00626 C$Space set $20 002E ( turbos.d):00627 C$Period set '. 002C ( turbos.d):00628 C$Comma set ', 000D ( turbos.d):00629 C$CR set $0D 000A ( turbos.d):00630 C$LF set $0A ( turbos.d):00631 ( turbos.d):00632 endc ( defs.d):00034 ( defs.d):00035 * CoCo specific definitions ( defs.d):00036 ( defs.d):00037 * CoCo mapped I/O boundaries FF00 ( defs.d):00038 MappedIOStart equ $FF00 FFEF ( defs.d):00039 MappedIOEnd equ $FFEF ( defs.d):00040 ( defs.d):00041 * CoCo ticks per second support 003C ( defs.d):00042 TkPerSec set 60 ( go.asm):00019 0011 ( go.asm):00020 tylg set Prgrm+Objct ; module type/language: executable object 0081 ( go.asm):00021 atrv set ReEnt+rev ; module attributes/revision byte 0001 ( go.asm):00022 rev set $01 ; module revision value 0001 ( go.asm):00023 edition set 1 ; module edition byte ( go.asm):00024 0000 87CD01BA000D1181 ( go.asm):00025 mod eom,name,tylg,atrv,start,size ; declare OS-9/TurbOS module header 93001000CE ( go.asm):00026 ( go.asm):00027 org 0 ; begin module static storage layout 0000. ( go.asm):00028 screenstart rmb 2 ; 512-byte-aligned VDG screen base address 0002. ( go.asm):00029 screenend rmb 2 ; first address beyond the VDG screen buffer 0004. ( go.asm):00030 nextcharpos rmb 2 ; next character cell to write 0006. ( go.asm):00031 stack rmb 200 ; process stack space requested by module 00CE ( go.asm):00032 size equ . ; total static storage requirement ( go.asm):00033 000D 67EF ( go.asm):00034 name fcs /go/ ; module name string 000F 01 ( go.asm):00035 fcb edition ; module edition byte ( go.asm):00036 ( go.asm):00037 * This is a CoCo-specific program that prints a few characters onto the VDG ( go.asm):00038 * screen area of the CoCo. It's meant to demonstrate that the kernel is ( go.asm):00039 * functioning and works. ( go.asm):00040 * ( go.asm):00041 * This program allocates 512 bytes for the 32x16 VDG screen and writes to that area. 0010 ( go.asm):00042 start 0010 1700C2 ( go.asm):00043 lbsr VDGInit ; allocate and map a VDG text screen 0013 2575 ( go.asm):00044 bcs exit ; exit if screen setup failed 0015 170110 ( go.asm):00045 lbsr ClearScreen ; blank the newly allocated screen ( go.asm):00046 003C ( go.asm):00047 _SLEEP_TIME equ TkPerSec ; delay between screen refreshes 0018 308D0168 ( go.asm):00048 leax banner,pcr ; point X at the static screen labels 001C 17006E ( go.asm):00049 lbsr VDGWrite ; render labels before live values 001F ( go.asm):00050 loop 001F CC0030 ( go.asm):00051 ldd #(32*1)+16 ; select row 1, column 16 for D.Ticks 0022 E3C4 ( go.asm):00052 addd screenstart,u ; convert screen offset to absolute address 0024 ED44 ( go.asm):00053 std nextcharpos,u ; position the VDG writer at the tick field 0026 FC0059 ( go.asm):00054 ldd >D.Ticks ; read high word of the 32-bit system tick count 0029 170108 ( go.asm):00055 lbsr PRINT_HEX_16 ; print high word as four hex digits 002C FC005B ( go.asm):00056 ldd >D.Ticks+2 ; read low word of the 32-bit system tick count 002F 170102 ( go.asm):00057 lbsr PRINT_HEX_16 ; print low word as four hex digits 0032 308D017F ( go.asm):00058 leax crt,pcr ; point X at carriage-return terminator 0036 170054 ( go.asm):00059 lbsr VDGWrite ; advance to the next displayed row ( go.asm):00060 0039 CC0050 ( go.asm):00061 ldd #(32*2)+16 ; select row 2, column 16 for D.Slice 003C E3C4 ( go.asm):00062 addd screenstart,u ; convert screen offset to absolute address 003E ED44 ( go.asm):00063 std nextcharpos,u ; position the writer at the slice field 0040 F60048 ( go.asm):00064 ldb >D.Slice ; read the current process time-slice counter 0043 1700F6 ( go.asm):00065 lbsr PRINT_HEX_8 ; print slice value as two hex digits ( go.asm):00066 0046 308D016B ( go.asm):00067 leax crt,pcr ; point X at carriage-return terminator 004A 170040 ( go.asm):00068 lbsr VDGWrite ; advance to the next displayed row 004D CC0070 ( go.asm):00069 ldd #(32*3)+16 ; select row 3, column 16 for D.AProcQ 0050 E3C4 ( go.asm):00070 addd screenstart,u ; convert screen offset to absolute address 0052 ED44 ( go.asm):00071 std nextcharpos,u ; position the writer at active-queue field 0054 FC004D ( go.asm):00072 ldd >D.AProcQ ; read active process queue pointer 0057 1700DA ( go.asm):00073 lbsr PRINT_HEX_16 ; print active queue pointer ( go.asm):00074 005A 308D0157 ( go.asm):00075 leax crt,pcr ; point X at carriage-return terminator 005E 17002C ( go.asm):00076 lbsr VDGWrite ; advance to the next displayed row 0061 CC0090 ( go.asm):00077 ldd #(32*4)+16 ; select row 4, column 16 for D.SProcQ 0064 E3C4 ( go.asm):00078 addd screenstart,u ; convert screen offset to absolute address 0066 ED44 ( go.asm):00079 std nextcharpos,u ; position the writer at sleeping-queue field 0068 FC0051 ( go.asm):00080 ldd >D.SProcQ ; read sleeping process queue pointer 006B 1700C6 ( go.asm):00081 lbsr PRINT_HEX_16 ; print sleeping queue pointer ( go.asm):00082 006E 308D0143 ( go.asm):00083 leax crt,pcr ; point X at carriage-return terminator 0072 170018 ( go.asm):00084 lbsr VDGWrite ; advance to the next displayed row 0075 CC00B0 ( go.asm):00085 ldd #(32*5)+16 ; select row 5, column 16 for D.WProcQ 0078 E3C4 ( go.asm):00086 addd screenstart,u ; convert screen offset to absolute address 007A ED44 ( go.asm):00087 std nextcharpos,u ; position the writer at waiting-queue field 007C FC004F ( go.asm):00088 ldd >D.WProcQ ; read waiting process queue pointer 007F 1700B2 ( go.asm):00089 lbsr PRINT_HEX_16 ; print waiting queue pointer ( go.asm):00090 0082 8E003C ( go.asm):00091 ldx #_SLEEP_TIME ; request a short sleep between display updates 0085 103F0A ( go.asm):00092 os9 F$Sleep ; yield until the next tick 0088 2095 ( go.asm):00093 bra loop ; refresh the live values forever ( go.asm):00094 008A 103F06 ( go.asm):00095 exit os9 F$Exit ; terminate this process ( go.asm):00096 ( go.asm):00097 * Write a null-terminated string to the VDG screen. ( go.asm):00098 * Entry: X = address of string to write. ( go.asm):00099 * Uses nextcharpos,u as the current cursor and updates it on exit. 008D 10AE44 ( go.asm):00100 VDGWrite ldy nextcharpos,u ; load destination screen pointer 0090 A680 ( go.asm):00101 loop@ lda ,x+ ; fetch next source character and advance X 0092 273D ( go.asm):00102 beq ex1@ ; stop at the null terminator 0094 810D ( go.asm):00103 cmpa #C$CR ; detect carriage return 0096 2612 ( go.asm):00104 bne fixchar@ ; handle printable characters normally 0098 EC44 ( go.asm):00105 ldd nextcharpos,u ; fetch current cursor address 009A C30020 ( go.asm):00106 addd #32 ; move to the same column on the next row 009D C4E0 ( go.asm):00107 andb #%11100000 ; force column zero by clearing low five bits 009F 10A342 ( go.asm):00108 cmpd screenend,u ; test whether the new row is past the screen 00A2 2C13 ( go.asm):00109 bge scroll@ ; scroll if the cursor moved off screen 00A4 ED44 ( go.asm):00110 std nextcharpos,u ; save the new row start as cursor position 00A6 1F02 ( go.asm):00111 tfr d,y ; use the same address as write pointer 00A8 20E6 ( go.asm):00112 bra loop@ ; continue scanning the string 00AA 8140 ( go.asm):00113 fixchar@ cmpa #$40 ; check whether character needs VDG ASCII bias 00AC 2402 ( go.asm):00114 bcc store@ ; characters at $40 and above are already VDG-ready 00AE 8B40 ( go.asm):00115 adda #$40 ; bias ASCII control/space range into VDG display codes 00B0 A7A0 ( go.asm):00116 store@ sta ,y+ ; store character and advance screen pointer 00B2 10AC42 ( go.asm):00117 cmpy screenend,u ; test for end of 32x16 text buffer 00B5 2DD9 ( go.asm):00118 blt loop@ ; continue if still inside the screen 0001 ( go.asm):00119 truescroll set 1 ; choose true scroll instead of wraparound 00B7 ( go.asm):00120 scroll@ ( go.asm):00121 IFEQ truescroll ( go.asm):00122 ldy screenstart,u ; wrap cursor to top-left when true scroll is disabled ( go.asm):00123 sty nextcharpos,u ; save wrapped cursor ( go.asm):00124 ELSE 00B7 3430 ( go.asm):00125 pshs x,y ; preserve source and current screen pointers while scrolling 00B9 108E01E0 ( go.asm):00126 ldy #32*15 ; copy fifteen 32-byte rows upward 00BD AEC4 ( go.asm):00127 ldx screenstart,u ; start at the top row 00BF 308820 ( go.asm):00128 leax 32,x ; source begins at second row 00C2 EC81 ( go.asm):00129 scrollloop@ ldd ,x++ ; copy two VDG cells from next row 00C4 ED88DE ( go.asm):00130 std -34,x ; store them one row above the source 00C7 313E ( go.asm):00131 leay -2,y ; count two copied bytes 00C9 26F7 ( go.asm):00132 bne scrollloop@ ; keep copying until fifteen rows moved 00CB AF44 ( go.asm):00133 stx nextcharpos,u ; cursor lands at start of final row after scroll 00CD 3530 ( go.asm):00134 puls x,y ; restore string and screen pointers ( go.asm):00135 ENDC 00CF 20BF ( go.asm):00136 bra loop@ ; continue writing after scroll/wrap 00D1 10AF44 ( go.asm):00137 ex1@ sty nextcharpos,u ; save final cursor position 00D4 39 ( go.asm):00138 rts ; return to caller ( go.asm):00139 * Initialize a 32x16 VDG screen. ( go.asm):00140 * Stack frame after "pshs u": 0000 ( go.asm):00141 stk_vdg_saved_u equ 0 ; saved caller U while F$SRqMem returns memory in U 00D5 3440 ( go.asm):00142 VDGInit pshs u ; preserve module static storage pointer 00D7 CC0300 ( go.asm):00143 ldd #512+256 ; request screen plus one page for alignment slack 00DA 103F28 ( go.asm):00144 os9 F$SRqMem ; allocate memory; U returns allocation address 00DD 2547 ( go.asm):00145 bcs ex@ ; return error if memory allocation failed 00DF 1F30 ( go.asm):00146 good@ tfr u,d ; copy allocated address into D for alignment math 00E1 EEE4 ( go.asm):00147 ldu ,s ; restore module static storage pointer from stk_vdg_saved_u 00E3 1F89 ( go.asm):00148 tfr a,b ; save allocation high byte in B 00E5 8501 ( go.asm):00149 bita #$01 ; test whether allocation began on an odd page 00E7 2704 ( go.asm):00150 beq lastpage@ ; even page is already 512-byte aligned 00E9 8B01 ( go.asm):00151 adda #$01 ; use the following even page as VDG screen 00EB 2001 ( go.asm):00152 bra firstpage@ ; return the unneeded first page 00ED 5C ( go.asm):00153 lastpage@ incb ; return page after the aligned screen ( go.asm):00154 * Stack frame after "pshs u,a": 0000 ( go.asm):00155 stk_vdg_screen equ 0 ; selected screen high byte 0001 ( go.asm):00156 stk_vdg_saved_u2 equ 1 ; saved module static storage pointer 00EE 3442 ( go.asm):00157 firstpage@ pshs u,a ; save static pointer and selected screen page 00F0 1F98 ( go.asm):00158 tfr b,a ; move high byte of page to return into A 00F2 5F ( go.asm):00159 clrb ; make D point to start of page being returned 00F3 1F03 ( go.asm):00160 tfr d,u ; pass return-page address in U 00F5 CC0100 ( go.asm):00161 ldd #256 ; return exactly one unused page 00F8 103F29 ( go.asm):00162 os9 F$SRtMem ; return alignment slack to the system pool 00FB 3542 ( go.asm):00163 puls u,a ; restore static pointer and selected screen page 00FD 258B ( go.asm):00164 bcs exit ; exit process if the memory return failed 00FF 5F ( go.asm):00165 clrb ; form selected screen base address in D 0100 EDC4 ( go.asm):00166 std screenstart,u ; save aligned VDG screen base 0102 ED44 ( go.asm):00167 std nextcharpos,u ; initialize cursor to top-left 0104 C30200 ( go.asm):00168 addd #32*16 ; compute one byte past 32x16 screen 0107 ED42 ( go.asm):00169 std screenend,u ; save end-of-screen address 0109 A6C4 ( go.asm):00170 lda screenstart,u ; get high byte of screen base for SAM setup ( go.asm):00171 * Set up VDG alpha mode screen for text. 010B 8EFFC6 ( go.asm):00172 ldx #$FFC6 ; point at highest SAM display-offset select address 010E E71A ( go.asm):00173 stb -6,x ; clear SAM VDG mode/address select bit at $FFC0 0110 E71C ( go.asm):00174 stb -4,x ; clear SAM VDG mode/address select bit at $FFC2 0112 E71E ( go.asm):00175 stb -2,x ; clear SAM VDG mode/address select bit at $FFC4 0114 C607 ( go.asm):00176 ldb #$07 ; program seven SAM address-select bit pairs 0116 44 ( go.asm):00177 lsra ; discard low bit not used by SAM screen base 0117 44 ( go.asm):00178 loop1@ lsra ; shift next screen-base bit into carry 0118 2504 ( go.asm):00179 bcs odd@ ; choose odd SAM register address when bit is set 011A A781 ( go.asm):00180 sta ,x++ ; tickle even SAM register address when bit is clear 011C 2004 ( go.asm):00181 bra next@ ; advance to next SAM bit pair 011E 3001 ( go.asm):00182 odd@ leax 1,x ; skip even SAM register address 0120 A780 ( go.asm):00183 sta ,x+ ; tickle odd SAM register address when bit is set 0122 5A ( go.asm):00184 next@ decb ; count programmed SAM bit pair 0123 26F2 ( go.asm):00185 bne loop1@ ; continue until all seven bits are programmed 0125 5F ( go.asm):00186 clrb ; clear carry to report success 0126 35C0 ( go.asm):00187 ex@ puls u,pc ; restore static pointer and return ( go.asm):00188 0128 ( go.asm):00189 ClearScreen 0128 AEC4 ( go.asm):00190 ldx screenstart,u ; point X at first VDG screen byte 012A CC6060 ( go.asm):00191 ldd #(C$SPACE+$40)*256+(C$SPACE+$40) ; prepare two VDG space characters 012D ED81 ( go.asm):00192 loop@ std ,x++ ; clear two screen cells and advance 012F AC42 ( go.asm):00193 cmpx screenend,u ; test whether screen end was reached 0131 26FA ( go.asm):00194 bne loop@ ; keep clearing until the full screen is blank 0133 39 ( go.asm):00195 rts ; return after clearing screen ( go.asm):00196 ( go.asm):00197 ************************************* ( go.asm):00198 * Print 4 digit (16-bit) hex number. ( go.asm):00199 * ( go.asm):00200 * Entry: D = value to print ( go.asm):00201 * ( go.asm):00202 * Exit: B error code, if any ( go.asm):00203 * CC carry set if error ( go.asm):00204 * ( go.asm):00205 * Stack frame after "pshs b": 0000 ( go.asm):00206 stk_hex16_low_byte equ 0 ; original low byte while high byte is printed 0134 ( go.asm):00207 PRINT_HEX_16 0134 3404 ( go.asm):00208 pshs b ; save low byte for second pair of hex digits 0136 1F89 ( go.asm):00209 tfr a,b ; move high byte into B for PRINT_HEX_8 0138 8D02 ( go.asm):00210 bsr PRINT_HEX_8 ; print high byte as two hex digits 013A E6E0 ( go.asm):00211 ldb ,s+ ; recover original low byte from stk_hex16_low_byte ( go.asm):00212 * Fall through to PRINT_HEX_8. ( go.asm):00213 ( go.asm):00214 ************************************* ( go.asm):00215 * Print 2 digit (8-bit) hex number. ( go.asm):00216 * ( go.asm):00217 * Entry: B = value to print ( go.asm):00218 * ( go.asm):00219 * Exit: B = error code, if any ( go.asm):00220 * CC = carry set if error ( go.asm):00221 * ( go.asm):00222 * Stack frame after "pshs a,x" and "leas -3,s": 0000 ( go.asm):00223 stk_hex8_buffer equ 0 ; three-byte null-terminated output buffer 0003 ( go.asm):00224 stk_hex8_saved_x equ 3 ; saved X register 0005 ( go.asm):00225 stk_hex8_saved_a equ 5 ; saved A register 0006 ( go.asm):00226 stk_hex8_return equ 6 ; return address to caller 013C ( go.asm):00227 PRINT_HEX_8 013C 3412 ( go.asm):00228 pshs a,x ; preserve registers clobbered by conversion/write 013E 327D ( go.asm):00229 leas -3,s ; reserve two hex digits plus null terminator 0140 1F41 ( go.asm):00230 tfr s,x ; pass stack buffer address in X 0142 17001B ( go.asm):00231 lbsr BIN_HEX_8 ; convert B to null-terminated hex string 0145 17FF45 ( go.asm):00232 lbsr VDGWrite ; write converted string to VDG screen 0148 3263 ( go.asm):00233 leas 3,s ; release local buffer 014A 3592 ( go.asm):00234 puls a,x,pc ; restore registers and return ( go.asm):00235 ( go.asm):00236 ******************************************** ( go.asm):00237 * Binary to hexadecimal convertor ( go.asm):00238 * ( go.asm):00239 * This subroutine will convert the binary value in ( go.asm):00240 * 'D' to a 4 digit hexadecimal ASCII string. ( go.asm):00241 * ( go.asm):00242 * OTHER MODULES NEEDED: BIN2HEX ( go.asm):00243 * ( go.asm):00244 * Entry: D = value to convert ( go.asm):00245 * X = buffer for hex string-null terminated ( go.asm):00246 * ( go.asm):00247 * Exit: all registers (except CC) preserved. ( go.asm):00248 * ( go.asm):00249 * Stack frame after "pshs d,x": 0000 ( go.asm):00250 stk_bin16_saved_x equ 0 ; caller output buffer pointer 0002 ( go.asm):00251 stk_bin16_saved_d equ 2 ; caller 16-bit value 014C ( go.asm):00252 bin_hex_16: 014C 3416 ( go.asm):00253 pshs d,x ; preserve input value and buffer pointer 014E E6E4 ( go.asm):00254 ldb ,s ; load high byte from stk_bin16_saved_d 0150 17001A ( go.asm):00255 lbsr BIN2HEX ; convert byte in B to two ASCII hex digits in D 0153 ED81 ( go.asm):00256 std ,x++ ; store first two digits and advance buffer 0155 E661 ( go.asm):00257 ldb 1,s ; load low byte from stk_bin16_saved_d+1 0157 170013 ( go.asm):00258 lbsr BIN2HEX ; convert low byte to ASCII hex 015A ED81 ( go.asm):00259 std ,x++ ; store second two digits and advance buffer 015C 6F84 ( go.asm):00260 clr ,x ; terminate output string with NUL 015E 3516 ( go.asm):00261 puls d,x ; restore caller registers ( go.asm):00262 ( go.asm):00263 * Stack frame after "pshs b,x": 0000 ( go.asm):00264 stk_bin8_saved_x equ 0 ; caller output buffer pointer 0002 ( go.asm):00265 stk_bin8_saved_b equ 2 ; caller byte value 0160 ( go.asm):00266 bin_hex_8: 0160 3414 ( go.asm):00267 pshs b,x ; preserve input byte and buffer pointer 0162 E6E4 ( go.asm):00268 ldb ,s ; reload byte from stk_bin8_saved_b 0164 170006 ( go.asm):00269 lbsr BIN2HEX ; convert byte in B to two ASCII hex digits in D 0167 ED81 ( go.asm):00270 std ,x++ ; store converted byte and advance buffer 0169 6F84 ( go.asm):00271 clr ,x ; terminate output string with NUL 016B 3514 ( go.asm):00272 puls b,x ; restore caller registers ( go.asm):00273 ( go.asm):00274 **************************************** ( go.asm):00275 * Convert hex byte to 2 hex digits. ( go.asm):00276 * ( go.asm):00277 * OTHER MODULES REQUIRED: none ( go.asm):00278 * ( go.asm):00279 * Entry: B = value to convert ( go.asm):00280 * ( go.asm):00281 * Exit: D = 2 byte hex digits ( go.asm):00282 * ( go.asm):00283 * Stack frame after "pshs b": 0000 ( go.asm):00284 stk_bin2hex_lsn equ 0 ; original byte used later for low nibble 016D ( go.asm):00285 BIN2HEX 016D 3404 ( go.asm):00286 pshs b ; save original byte for low-nibble conversion 016F 54 ( go.asm):00287 lsrb ; move high nibble toward low nibble bit 3 0170 54 ( go.asm):00288 lsrb ; move high nibble toward low nibble bit 2 0171 54 ( go.asm):00289 lsrb ; move high nibble toward low nibble bit 1 0172 54 ( go.asm):00290 lsrb ; move high nibble into low nibble position 0173 8D06 ( go.asm):00291 bsr ToHex ; convert high nibble to ASCII in B 0175 1F98 ( go.asm):00292 tfr b,a ; save first ASCII digit in A 0177 3504 ( go.asm):00293 puls b ; restore original byte for low nibble 0179 C40F ( go.asm):00294 andb #%00001111 ; isolate low nibble ( go.asm):00295 017B ( go.asm):00296 ToHex 017B CB30 ( go.asm):00297 addb #'0 ; bias nibble into ASCII digit range 017D C139 ( go.asm):00298 cmpb #'9 ; test whether digit is 0-9 017F 2302 ( go.asm):00299 bls ToHex1 ; return if ASCII digit is in numeric range 0181 CB07 ( go.asm):00300 addb #7 ; adjust ':' through '?' into 'A' through 'F' 0183 ( go.asm):00301 ToHex1 0183 39 ( go.asm):00302 rts ; return with ASCII hex digit in B ( go.asm):00303 0184 545552424F53 ( go.asm):00304 banner fcc /TURBOS/ ; display title string 018A 0D ( go.asm):00305 fcb C$CR ; move to next VDG row 018B 442E5449434B53 ( go.asm):00306 fcc /D.TICKS/ ; label for 32-bit system tick counter 0192 0D ( go.asm):00307 fcb C$CR ; move to next VDG row 0193 442E534C494345 ( go.asm):00308 fcc /D.SLICE/ ; label for process time-slice counter 019A 0D ( go.asm):00309 fcb C$CR ; move to next VDG row 019B 442E4150524F4351 ( go.asm):00310 fcc /D.APROCQ/ ; label for active process queue pointer 01A3 0D ( go.asm):00311 fcb C$CR ; move to next VDG row 01A4 442E5350524F4351 ( go.asm):00312 fcc /D.SPROCQ/ ; label for sleeping process queue pointer 01AC 0D ( go.asm):00313 fcb C$CR ; move to next VDG row 01AD 442E5750524F4351 ( go.asm):00314 fcc /D.WPROCQ/ ; label for waiting process queue pointer 01B5 0D00 ( go.asm):00315 crt fcb C$CR,$00 ; carriage return plus string terminator ( go.asm):00316 01B7 3328B5 ( go.asm):00317 emod ; emit module CRC 01BA ( go.asm):00318 eom equ * ; end of module address ( go.asm):00319 end ; end assembly