›MODULE ; CMPTODSK.ACT››; Copyright (c) 1983›; by Action Computer Services›; All Rights Reserved››; version 1.0›; last modified October 22, 1984››; Compile to disk for ACTION! ›; compiler. Note that all ARRAY›; declarations that generate storage›; must be before the first procedure›; declaration or else the address of›; the storage will not be setup›; correctly (all dimensioned ARRAYs›; which are not assigned an initial›; value except BYTE/CHAR arrays of›; size 256 or less). Local ARRAY›; declarations in the main PROC (last›; procedure in program) are also›; allowed. Note: there must be at ›; least one PROC/FUNC in program.››; Output file name will be same name›; as program being compiled with›; extention .OBJ››; IF AN ERROR OCCURS DURING›; COMPILATION, YOU SHOULD USE›; "/" to close all open files:›; >/››; change dev in SPLEnd below to direct›; output to printer.››DEFINE STRING = "CHAR ARRAY"›DEFINE JMP = "$4C" ; JMP addr16››TYPE INSTR=[BYTE op CARD addr]›INSTR Segvec=$4C6›INSTR SPLvec=$4DD›INSTR MonCmd=$4FB›INSTR OldMon››BYTE oldDevice, curBank=$4C9›BYTE pf, Zop=$8A, tZop, dev›CARD curproc=$8E, code=$E›CARD codeBase=$491, codeSize=$493›CARD codeOff=$B5›CARD globals, gsize›CARD totalSize, codeStart›CHAR ARRAY cmdLine(0)=$590›BYTE ARRAY bank(0)=$D500›BYTE ARRAY zpage(32), temps(16)›››PROC InitMon()›; add "/" command to monitor which›; closes channels 1-5 and warm›; starts cartridge.›› CHAR cmdchar=$591› BYTE i, WARMST=$8› DEFINE JMPI="$6C"››; make sure right command› IF cmdchar#'/ THEN [JMP OldMon] FI›› bank(0) = 0 ; init library routines› FOR i = 1 TO 5 DO› Close(i)› OD›› WARMST = 1›[JMPI $BFFA] ; warm start cart.›››INCLUDE "runtime.act"›››PROC Save()›; save state of variables used by›; both compiler and library routines›› bank(0) = 0 ; init library routines› tZop = Zop› MoveBlock(zpage, $B0, $1B) ; to $CA› MoveBlock(temps, $5F0, 16)›RETURN›››PROC Restore()›; restore state of variables used by›; both compiler and library routines› CARD tcodeOff›› Zop = tZop› tcodeOff = codeOff› MoveBlock($B0, zpage, $1B) ; to $CA› MoveBlock($5F0, temps, 16)› codeOff = tcodeOff›› bank(curBank) = 0›RETURN›››PROC WriteHdr()› PutCD(5, $FFFF)› PutCD(5, codeStart)› PutCD(5, codeStart+totalSize-1)› WriteBlock(5, globals, gsize)›RETURN›››PROC WriteCode()› codeSize = code - codeBase› PrintD(dev, curproc)› PrintD(dev, ": ")› PrintCDE(dev, codeSize)› totalSize = totalSize + codeSize› WriteBlock(5, codeBase, codeSize)› code = codeBase› codeOff = codeOff + codeSize›RETURN›››PROC SegEnd()› Save()› IF pf THEN ; print locals› WriteCode()› ELSE› pf = 1› globals = codeBase› gsize = code - codeBase› codeBase = code› totalSize = gsize› codeStart = globals + codeOff› WriteHdr()› FI› Restore()›RETURN›››PROC SPL() ; dummy proc for call below›››PROC SPLEnd()› CHAR c› BYTE nxttoken=$D3, i, n, buf=$9B^› CARD nxtaddr=$C9, start=$2E2› STRING inbuf(0)=$5C8, name› STRING out(17)›› DEFINE PLA = "$68",› STA = "$8D"›› Save()›› dev = 0›; to get output to printer:›; dev = 4›; Close(4) Open(4, "P:", 8, 0)››; get output name› IF nxttoken=30 THEN ; command line› name = nxtaddr› ELSE ; editor buffer› name = inbuf› FI››; see if device needed› n = 0› IF name(2)#': AND name(3)#': THEN› out(1) = 'D out(2) = ': n = 2› FI››; get name without extension› FOR i = 1 TO name(0) DO› c = name(i)› IF c='. THEN EXIT FI› IF c>'Z THEN c = c & $5F FI› out(i+n) = c › OD››; add extension› out(i+n) = '.› out(i+n+1) = 'O› out(i+n+2) = 'B› out(i+n+3) = 'J› out(0) = i + n + 3›› PutE()› Print("output file is ")› PrintE(out)› PutE()›› Close(5) Open(5, out, 8, 0)› buf = 0 ; clear buf used by Open›› pf = 0 ; no proc decl yet››; JSR for return so that we come›; back here after compilation› [ › PLA› STA SPL+1› PLA› STA SPL+2› ]› SPL = SPL + 1 ; get right address› Restore()›› SPL()›› Save()››; ignore space for arrays› code = codeBase + codeSize›› WriteCode()› PutCD(5, $2E2)› PutCD(5, $2E3)› PutCD(5, start)› Close(5)›› Open(5, out, $C, 0)› WriteHdr()› Close(5)›› PutDE(dev)› PrintCD(dev, totalSize)› PrintDE(dev, " bytes of code")›› Restore()› codeOff = 0›RETURN›››; only code generated before Init is›; allocated space. Init will be›; garbage collected (well kind of).››PROC Init()› CARD codeBlock, bsize, csize, nBlock› CARD POINTER cur, next››; link in our routines› Segvec.op = JMP› Segvec.addr = SegEnd› SPLvec.op = JMP› SPLvec.addr = SPLEnd› OldMon.op = MonCmd.op› OldMon.addr = MonCmd.addr› MonCmd.op = JMP› MonCmd.addr = InitMon››; allocate our routine so it won't›; go away.› codeBlock = codeBase - 4› next = $80 ; AFbase› DO› cur = next› next = next^› UNTIL next=0 OR next=codeBlock OD›› IF next=0 THEN› PutE() Put($FD)› PrintE("I can't allocate space for your code")› PrintE("You better Boot and try again!")› RETURN› FI››; assume we can split block› csize = @codeBlock-codeBlock› nBlock = next^› bsize = next(1) - csize› next = @codeBlock› cur^ = next› next^ = nBlock› next(1) = bsize› codeBase = next + 4›RETURN››