CMPTODSK.ACT z Action! wiki ma jeden mały błąd w linii
IF c>'Z THEN c = c & $5F FI
a brakujący include BLKIO.ACT za niedługo może być trudny do znalezienia. Wrzucam tu dla porządku, bo kompilacja do pliku to przydatna rzecz.
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 "H1: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
MODULE ; BLKIO.ACT ; Copyright (c) 1983, 1984, 1985 ; by Action Computer Services (ACS) ; This software may be incorporated in ; other software packages providing ; that this copyright notice is also ; incorporated as well. ; version 1.1 ; last modified May 8, 1985 BYTE CIO_status CHAR FUNC CIO=*(BYTE dev, CARD addr, size, BYTE cmd, aux1, aux2) ; see hardware manual for description ; of CIOV. ; IOCB# = dev ; ICCOM = cmd ; ICBA = addr ; ICBL = size ; ICAX1 = aux1 ; ICAX2 = aux2 ; ICAX1 and ICAX2 are not set if aux1=0 ; The first byte of addr is passed to ; CIO in the A register. The status ; on return from CIO is stored in ; CIO_status. If status=$88 then ; EOF(dev) is set to a non-zero value. ; No other error checking is performed ; and the result of the CIOV call is ; returned as the result of this FUNC. [$29$F$85$A0$86$A1$A$A$A$A$AA$A5$A5 $9D$342$A5$A3$9D$348$A5$A4$9D$349 $A5$A6$F0$8$9D$34A$A5$A7$9D$34B$98 $9D$345$A5$A1$9D$344$20$E456 $8C CIO_status$C0$88$D0$6$98$A4$A0 $99 EOF$A085$60] CARD FUNC ReadBlock=*(BYTE dev, CARD addr, size) ; Reads size bytes from dev into addr. ; Returns number of bytes read (may ; be < size if EOF). Set EOF flag if ; EOF is encountered. Status is ; saved in CIO_status. [$48$A9$7$85$A5$A9$0$85$A6$A5$A3$5$A4 $D0$6$85$A0$85$A1$68$60$68$20 CIO $BD$348$85$A0$BD$349$85$A1$60] PROC WriteBlock=*(BYTE dev, CARD addr, size) ; Writes size bytes from addr to dev. ; Status is saved in CIO_status. [$48$A9$B$85$A5$A9$0$85$A6$A5$A3$5$A4 $D0$2$68$60$68$4C CIO] PROC PutCD=*(BYTE chan, CARD n) BYTE c=$AA, lo=$AB, hi=$AC ; save args [ $85 c $86 lo $84 hi ] ; PutD(c, lo) ; PutD(c, hi) CIO(c,lo,0,11,0) CIO(c,hi,0,11,0) RETURN CARD FUNC GetCD(BYTE chan) CARD out BYTE lo=out, hi=out+1 ; lo = GetD(chan) ; hi = GetD(chan) lo = CIO(chan,0,0,7,0) hi = CIO(chan,0,0,7,0) RETURN(out) MODULE ; for user
Działa to podobnie jak symbol table lister:
- uruchamiamy CMPTODSK.ACT w monitorze (bez ładowania do edytora):
Ctrl+Shift+M, R „H1:CMPTODSK.ACT” - wychodzimy do edytora, ładujemy nasz program Ctrl+Shift+R, H1:PLIK.ACT
- kompilujemy Ctrl+Shift+M, C
- skompilowany plik binarny zostaje zapisany pod nazwą H1:PLIK.OBJ
Teoretycznie to kolejny sposób na małą ilość pamięci i kompilowanie większych kawałków kodu Action!