General Information
Author: Action Computer Services
Language: ACTION!
Compiler/Interpreter: ACTION!
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.
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 "BLKIO.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